Mercurial > libpst
comparison src/vbuf.c @ 172:6954d315aaa8
move version-info into main configure.in, and set it properly.
prefix all external symbols in the shared library with pst_ to avoid symbol clashes with other shared libraries.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 04 Apr 2009 16:00:48 -0700 |
parents | ab384fed78c5 |
children | ac6e22c8a9cf |
comparison
equal
deleted
inserted
replaced
171:6c1e75bc4cac | 172:6954d315aaa8 |
---|---|
3 | 3 |
4 | 4 |
5 #define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); } | 5 #define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); } |
6 | 6 |
7 | 7 |
8 int skip_nl(char *s) | 8 int pst_skip_nl(char *s) |
9 { | 9 { |
10 if (s[0] == '\n') | 10 if (s[0] == '\n') |
11 return 1; | 11 return 1; |
12 if (s[0] == '\r' && s[1] == '\n') | 12 if (s[0] == '\r' && s[1] == '\n') |
13 return 2; | 13 return 2; |
15 return 0; | 15 return 0; |
16 return -1; | 16 return -1; |
17 } | 17 } |
18 | 18 |
19 | 19 |
20 int find_nl(vstr * vs) | 20 int pst_find_nl(vstr * vs) |
21 { | 21 { |
22 char *nextr, *nextn; | 22 char *nextr, *nextn; |
23 | 23 |
24 nextr = memchr(vs->b, '\r', vs->dlen); | 24 nextr = memchr(vs->b, '\r', vs->dlen); |
25 nextn = memchr(vs->b, '\n', vs->dlen); | 25 nextn = memchr(vs->b, '\n', vs->dlen); |
47 static int target_open_to = 0; | 47 static int target_open_to = 0; |
48 static iconv_t i8totarget = (iconv_t)-1; | 48 static iconv_t i8totarget = (iconv_t)-1; |
49 static iconv_t target2i8 = (iconv_t)-1; | 49 static iconv_t target2i8 = (iconv_t)-1; |
50 | 50 |
51 | 51 |
52 void unicode_init() | 52 void pst_unicode_init() |
53 { | 53 { |
54 if (unicode_up) unicode_close(); | 54 if (unicode_up) pst_unicode_close(); |
55 i16to8 = iconv_open("utf-8", "utf-16le"); | 55 i16to8 = iconv_open("utf-8", "utf-16le"); |
56 if (i16to8 == (iconv_t)-1) { | 56 if (i16to8 == (iconv_t)-1) { |
57 WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n")); | 57 WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n")); |
58 exit(1); | 58 exit(1); |
59 } | 59 } |
60 unicode_up = 1; | 60 unicode_up = 1; |
61 } | 61 } |
62 | 62 |
63 | 63 |
64 void unicode_close() | 64 void pst_unicode_close() |
65 { | 65 { |
66 iconv_close(i16to8); | 66 iconv_close(i16to8); |
67 if (target_open_from) iconv_close(i8totarget); | 67 if (target_open_from) iconv_close(i8totarget); |
68 if (target_open_to) iconv_close(target2i8); | 68 if (target_open_to) iconv_close(target2i8); |
69 if (target_charset) free((char *)target_charset); | 69 if (target_charset) free((char *)target_charset); |
72 target_open_to = 0; | 72 target_open_to = 0; |
73 unicode_up = 0; | 73 unicode_up = 0; |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 int utf16_is_terminated(const char *str, int length) | 77 static int utf16_is_terminated(const char *str, int length); |
78 static int utf16_is_terminated(const char *str, int length) | |
78 { | 79 { |
79 VSTR_STATIC(errbuf, 100); | 80 VSTR_STATIC(errbuf, 100); |
80 int len = -1; | 81 int len = -1; |
81 int i; | 82 int i; |
82 for (i = 0; i < length; i += 2) { | 83 for (i = 0; i < length; i += 2) { |
84 len = i; | 85 len = i; |
85 } | 86 } |
86 } | 87 } |
87 | 88 |
88 if (-1 == len) { | 89 if (-1 == len) { |
89 vshexdump(errbuf, str, 0, length, 1); | 90 pst_vshexdump(errbuf, str, 0, length, 1); |
90 DEBUG_WARN(("String is not zero terminated (probably broken data from registry) %s.\n", errbuf->b)); | 91 DEBUG_WARN(("String is not zero terminated (probably broken data from registry) %s.\n", errbuf->b)); |
91 } | 92 } |
92 | 93 |
93 return (-1 == len) ? 0 : 1; | 94 return (-1 == len) ? 0 : 1; |
94 } | 95 } |
95 | 96 |
96 | 97 |
97 size_t vb_utf16to8(vbuf *dest, const char *inbuf, int iblen) | 98 size_t pst_vb_utf16to8(vbuf *dest, const char *inbuf, int iblen) |
98 { | 99 { |
99 size_t inbytesleft = iblen; | 100 size_t inbytesleft = iblen; |
100 size_t icresult = (size_t)-1; | 101 size_t icresult = (size_t)-1; |
101 size_t outbytesleft = 0; | 102 size_t outbytesleft = 0; |
102 char *outbuf = NULL; | 103 char *outbuf = NULL; |
103 int myerrno; | 104 int myerrno; |
104 | 105 |
105 ASSERT(unicode_up, "vb_utf16to8() called before unicode started."); | 106 ASSERT(unicode_up, "vb_utf16to8() called before unicode started."); |
106 vbresize(dest, iblen); | 107 pst_vbresize(dest, iblen); |
107 | 108 |
108 //Bad Things can happen if a non-zero-terminated utf16 string comes through here | 109 //Bad Things can happen if a non-zero-terminated utf16 string comes through here |
109 if (!utf16_is_terminated(inbuf, iblen)) | 110 if (!utf16_is_terminated(inbuf, iblen)) |
110 return (size_t)-1; | 111 return (size_t)-1; |
111 | 112 |
113 outbytesleft = dest->blen - dest->dlen; | 114 outbytesleft = dest->blen - dest->dlen; |
114 outbuf = dest->b + dest->dlen; | 115 outbuf = dest->b + dest->dlen; |
115 icresult = iconv(i16to8, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); | 116 icresult = iconv(i16to8, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); |
116 myerrno = errno; | 117 myerrno = errno; |
117 dest->dlen = outbuf - dest->b; | 118 dest->dlen = outbuf - dest->b; |
118 if (inbytesleft) vbgrow(dest, inbytesleft); | 119 if (inbytesleft) pst_vbgrow(dest, inbytesleft); |
119 } while ((size_t)-1 == icresult && E2BIG == myerrno); | 120 } while ((size_t)-1 == icresult && E2BIG == myerrno); |
120 | 121 |
121 if (icresult == (size_t)-1) { | 122 if (icresult == (size_t)-1) { |
122 DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); | 123 DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); |
123 unicode_init(); | 124 pst_unicode_init(); |
124 return (size_t)-1; | 125 return (size_t)-1; |
125 } | 126 } |
126 return (icresult) ? (size_t)-1 : 0; | 127 return (icresult) ? (size_t)-1 : 0; |
127 } | 128 } |
128 | 129 |
158 size_t icresult = (size_t)-1; | 159 size_t icresult = (size_t)-1; |
159 size_t outbytesleft = 0; | 160 size_t outbytesleft = 0; |
160 char *outbuf = NULL; | 161 char *outbuf = NULL; |
161 int myerrno; | 162 int myerrno; |
162 | 163 |
163 vbresize(dest, 2*iblen); | 164 pst_vbresize(dest, 2*iblen); |
164 | 165 |
165 do { | 166 do { |
166 outbytesleft = dest->blen - dest->dlen; | 167 outbytesleft = dest->blen - dest->dlen; |
167 outbuf = dest->b + dest->dlen; | 168 outbuf = dest->b + dest->dlen; |
168 icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); | 169 icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); |
169 myerrno = errno; | 170 myerrno = errno; |
170 dest->dlen = outbuf - dest->b; | 171 dest->dlen = outbuf - dest->b; |
171 if (inbytesleft) vbgrow(dest, 2*inbytesleft); | 172 if (inbytesleft) pst_vbgrow(dest, 2*inbytesleft); |
172 } while ((size_t)-1 == icresult && E2BIG == myerrno); | 173 } while ((size_t)-1 == icresult && E2BIG == myerrno); |
173 | 174 |
174 if (icresult == (size_t)-1) { | 175 if (icresult == (size_t)-1) { |
175 DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); | 176 DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno))); |
176 unicode_init(); | 177 pst_unicode_init(); |
177 return (size_t)-1; | 178 return (size_t)-1; |
178 } | 179 } |
179 return (icresult) ? (size_t)-1 : 0; | 180 return (icresult) ? (size_t)-1 : 0; |
180 } | 181 } |
181 | 182 |
182 | 183 |
183 size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) | 184 size_t pst_vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) |
184 { | 185 { |
185 open_targets(charset); | 186 open_targets(charset); |
186 if (!target_open_from) return (size_t)-1; // failure to open the target | 187 if (!target_open_from) return (size_t)-1; // failure to open the target |
187 return sbcs_conversion(dest, inbuf, iblen, i8totarget); | 188 return sbcs_conversion(dest, inbuf, iblen, i8totarget); |
188 } | 189 } |
189 | 190 |
190 | 191 |
191 size_t vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset) | 192 size_t pst_vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset) |
192 { | 193 { |
193 open_targets(charset); | 194 open_targets(charset); |
194 if (!target_open_to) return (size_t)-1; // failure to open the target | 195 if (!target_open_to) return (size_t)-1; // failure to open the target |
195 return sbcs_conversion(dest, inbuf, iblen, target2i8); | 196 return sbcs_conversion(dest, inbuf, iblen, target2i8); |
196 } | 197 } |
197 | 198 |
198 | 199 |
199 vbuf *vballoc(size_t len) | 200 vbuf *pst_vballoc(size_t len) |
200 { | 201 { |
201 struct varbuf *result = malloc(sizeof(struct varbuf)); | 202 struct varbuf *result = malloc(sizeof(struct varbuf)); |
202 if (result) { | 203 if (result) { |
203 result->dlen = 0; | 204 result->dlen = 0; |
204 result->blen = 0; | 205 result->blen = 0; |
205 result->buf = NULL; | 206 result->buf = NULL; |
206 vbresize(result, len); | 207 pst_vbresize(result, len); |
207 } | 208 } |
208 else DIE(("malloc() failure")); | 209 else DIE(("malloc() failure")); |
209 return result; | 210 return result; |
210 } | 211 } |
211 | 212 |
212 | 213 |
213 void vbcheck(vbuf * vb) | 214 void pst_vbcheck(vbuf * vb) |
214 { | 215 { |
215 ASSERT(vb->b >= vb->buf, "vbcheck(): data not inside buffer"); | 216 ASSERT(vb->b >= vb->buf, "vbcheck(): data not inside buffer"); |
216 ASSERT((size_t)(vb->b - vb->buf) <= vb->blen, "vbcheck(): vb->b outside of buffer range."); | 217 ASSERT((size_t)(vb->b - vb->buf) <= vb->blen, "vbcheck(): vb->b outside of buffer range."); |
217 ASSERT(vb->dlen <= vb->blen, "vbcheck(): data length > buffer length."); | 218 ASSERT(vb->dlen <= vb->blen, "vbcheck(): data length > buffer length."); |
218 ASSERT(vb->blen < 1024 * 1024, "vbcheck(): blen is a bit large...hmmm."); | 219 ASSERT(vb->blen < 1024 * 1024, "vbcheck(): blen is a bit large...hmmm."); |
219 } | 220 } |
220 | 221 |
221 | 222 |
222 void vbfree(vbuf * vb) | 223 void pst_vbfree(vbuf * vb) |
223 { | 224 { |
224 free(vb->buf); | 225 free(vb->buf); |
225 free(vb); | 226 free(vb); |
226 } | 227 } |
227 | 228 |
228 | 229 |
229 void vbclear(struct varbuf *vb) // ditch the data, keep the buffer | 230 void pst_vbclear(struct varbuf *vb) // ditch the data, keep the buffer |
230 { | 231 { |
231 vbresize(vb, 0); | 232 pst_vbresize(vb, 0); |
232 } | 233 } |
233 | 234 |
234 | 235 |
235 void vbresize(struct varbuf *vb, size_t len) // DESTRUCTIVELY grow or shrink buffer | 236 void pst_vbresize(struct varbuf *vb, size_t len) // DESTRUCTIVELY grow or shrink buffer |
236 { | 237 { |
237 vb->dlen = 0; | 238 vb->dlen = 0; |
238 | 239 |
239 if (vb->blen >= len) { | 240 if (vb->blen >= len) { |
240 vb->b = vb->buf; | 241 vb->b = vb->buf; |
245 vb->b = vb->buf; | 246 vb->b = vb->buf; |
246 vb->blen = len; | 247 vb->blen = len; |
247 } | 248 } |
248 | 249 |
249 | 250 |
250 size_t vbavail(vbuf * vb) | 251 size_t pst_vbavail(vbuf * vb) |
251 { | 252 { |
252 return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf); | 253 return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf); |
253 } | 254 } |
254 | 255 |
255 | 256 |
256 void vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved | 257 void pst_vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved |
257 { | 258 { |
258 if (0 == len) | 259 if (0 == len) |
259 return; | 260 return; |
260 | 261 |
261 if (0 == vb->blen) { | 262 if (0 == vb->blen) { |
262 vbresize(vb, len); | 263 pst_vbresize(vb, len); |
263 return; | 264 return; |
264 } | 265 } |
265 | 266 |
266 if (vb->dlen + len > vb->blen) { | 267 if (vb->dlen + len > vb->blen) { |
267 if (vb->dlen + len < vb->blen * 1.5) | 268 if (vb->dlen + len < vb->blen * 1.5) |
268 len = vb->blen * 1.5; | 269 len = vb->blen * 1.5; |
269 char *nb = malloc(vb->blen + len); | 270 char *nb = pst_malloc(vb->blen + len); |
270 if (!nb) DIE(("malloc() failure")); | 271 if (!nb) DIE(("malloc() failure")); |
271 vb->blen = vb->blen + len; | 272 vb->blen = vb->blen + len; |
272 memcpy(nb, vb->b, vb->dlen); | 273 memcpy(nb, vb->b, vb->dlen); |
273 | 274 |
274 free(vb->buf); | 275 free(vb->buf); |
279 memcpy(vb->buf, vb->b, vb->dlen); | 280 memcpy(vb->buf, vb->b, vb->dlen); |
280 } | 281 } |
281 | 282 |
282 vb->b = vb->buf; | 283 vb->b = vb->buf; |
283 | 284 |
284 ASSERT(vbavail(vb) >= len, "vbgrow(): I have failed in my mission."); | 285 ASSERT(pst_vbavail(vb) >= len, "vbgrow(): I have failed in my mission."); |
285 } | 286 } |
286 | 287 |
287 | 288 |
288 void vbset(vbuf * vb, void *b, size_t len) // set vbuf b size=len, resize if necessary, relen = how much to over-allocate | 289 void pst_vbset(vbuf * vb, void *b, size_t len) // set vbuf b size=len, resize if necessary, relen = how much to over-allocate |
289 { | 290 { |
290 vbresize(vb, len); | 291 pst_vbresize(vb, len); |
291 memcpy(vb->b, b, len); | 292 memcpy(vb->b, b, len); |
292 vb->dlen = len; | 293 vb->dlen = len; |
293 } | 294 } |
294 | 295 |
295 | 296 |
296 void vsskipws(vstr * vs) | 297 void pst_vsskipws(vstr * vs) |
297 { | 298 { |
298 char *p = vs->b; | 299 char *p = vs->b; |
299 while ((size_t)(p - vs->b) < vs->dlen && isspace(p[0])) | 300 while ((size_t)(p - vs->b) < vs->dlen && isspace(p[0])) |
300 p++; | 301 p++; |
301 | 302 |
302 vbskip((vbuf *) vs, p - vs->b); | 303 pst_vbskip((vbuf *) vs, p - vs->b); |
303 } | 304 } |
304 | 305 |
305 | 306 |
306 // append len bytes of b to vbuf, resize if necessary | 307 // append len bytes of b to vbuf, resize if necessary |
307 void vbappend(struct varbuf *vb, void *b, size_t len) | 308 void pst_vbappend(struct varbuf *vb, void *b, size_t len) |
308 { | 309 { |
309 if (0 == vb->dlen) { | 310 if (0 == vb->dlen) { |
310 vbset(vb, b, len); | 311 pst_vbset(vb, b, len); |
311 return; | 312 return; |
312 } | 313 } |
313 vbgrow(vb, len); | 314 pst_vbgrow(vb, len); |
314 memcpy(vb->b + vb->dlen, b, len); | 315 memcpy(vb->b + vb->dlen, b, len); |
315 vb->dlen += len; | 316 vb->dlen += len; |
316 } | 317 } |
317 | 318 |
318 | 319 |
319 // dumps the first skip bytes from vbuf | 320 // dumps the first skip bytes from vbuf |
320 void vbskip(struct varbuf *vb, size_t skip) | 321 void pst_vbskip(struct varbuf *vb, size_t skip) |
321 { | 322 { |
322 ASSERT(skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer."); | 323 ASSERT(skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer."); |
323 vb->b += skip; | 324 vb->b += skip; |
324 vb->dlen -= skip; | 325 vb->dlen -= skip; |
325 } | 326 } |
326 | 327 |
327 | 328 |
328 // overwrite vbdest with vbsrc | 329 // overwrite vbdest with vbsrc |
329 void vboverwrite(struct varbuf *vbdest, struct varbuf *vbsrc) | 330 void pst_vboverwrite(struct varbuf *vbdest, struct varbuf *vbsrc) |
330 { | 331 { |
331 vbresize(vbdest, vbsrc->blen); | 332 pst_vbresize(vbdest, vbsrc->blen); |
332 memcpy(vbdest->b, vbsrc->b, vbsrc->dlen); | 333 memcpy(vbdest->b, vbsrc->b, vbsrc->dlen); |
333 vbdest->blen = vbsrc->blen; | 334 vbdest->blen = vbsrc->blen; |
334 vbdest->dlen = vbsrc->dlen; | 335 vbdest->dlen = vbsrc->dlen; |
335 } | 336 } |
336 | 337 |
337 | 338 |
338 vstr *vsalloc(size_t len) | 339 vstr *pst_vsalloc(size_t len) |
339 { | 340 { |
340 vstr *result = (vstr *) vballoc(len + 1); | 341 vstr *result = (vstr *) pst_vballoc(len + 1); |
341 vsset(result, ""); | 342 pst_vsset(result, ""); |
342 return result; | 343 return result; |
343 } | 344 } |
344 | 345 |
345 | 346 |
346 char *vsstr(vstr * vs) | 347 static char *pst_vsstr(vstr * vs); |
348 static char *pst_vsstr(vstr * vs) | |
347 { | 349 { |
348 return vs->b; | 350 return vs->b; |
349 } | 351 } |
350 | 352 |
351 | 353 |
352 size_t vslen(vstr * vs) | 354 size_t pst_vslen(vstr * vs) |
353 { | 355 { |
354 return strlen(vsstr(vs)); | 356 return strlen(pst_vsstr(vs)); |
355 } | 357 } |
356 | 358 |
357 | 359 |
358 void vsfree(vstr * vs) | 360 void pst_vsfree(vstr * vs) |
359 { | 361 { |
360 vbfree((vbuf *) vs); | 362 pst_vbfree((vbuf *) vs); |
361 } | 363 } |
362 | 364 |
363 | 365 |
364 void vscharcat(vstr * vb, int ch) | 366 void pst_vscharcat(vstr * vb, int ch) |
365 { | 367 { |
366 vbgrow((vbuf *) vb, 1); | 368 pst_vbgrow((vbuf *) vb, 1); |
367 vb->b[vb->dlen - 1] = ch; | 369 vb->b[vb->dlen - 1] = ch; |
368 vb->b[vb->dlen] = '\0'; | 370 vb->b[vb->dlen] = '\0'; |
369 vb->dlen++; | 371 vb->dlen++; |
370 } | 372 } |
371 | 373 |
372 | 374 |
373 // prependappend string str to vbuf, vbuf must already contain a valid string | 375 // prependappend string str to vbuf, vbuf must already contain a valid string |
374 void vsnprepend(vstr * vb, char *str, size_t len) | 376 void pst_vsnprepend(vstr * vb, char *str, size_t len) |
375 { | 377 { |
376 ASSERT(vb->b[vb->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string."); | 378 ASSERT(vb->b[vb->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string."); |
377 size_t sl = strlen(str); | 379 size_t sl = strlen(str); |
378 size_t n = (sl < len) ? sl : len; | 380 size_t n = (sl < len) ? sl : len; |
379 vbgrow((vbuf *) vb, n + 1); | 381 pst_vbgrow((vbuf *) vb, n + 1); |
380 memmove(vb->b + n, vb->b, vb->dlen - 1); | 382 memmove(vb->b + n, vb->b, vb->dlen - 1); |
381 memcpy(vb->b, str, n); | 383 memcpy(vb->b, str, n); |
382 vb->dlen += n; | 384 vb->dlen += n; |
383 vb->b[vb->dlen - 1] = '\0'; | 385 vb->b[vb->dlen - 1] = '\0'; |
384 } | 386 } |
385 | 387 |
386 | 388 |
387 // len < dlen-1 -> skip len chars, else DIE | 389 // len < dlen-1 -> skip len chars, else DIE |
388 void vsskip(vstr * vs, size_t len) | 390 void pst_vsskip(vstr * vs, size_t len) |
389 { | 391 { |
390 ASSERT(len < vs->dlen - 1, "Attempt to skip past end of string"); | 392 ASSERT(len < vs->dlen - 1, "Attempt to skip past end of string"); |
391 vbskip((vbuf *) vs, len); | 393 pst_vbskip((vbuf *) vs, len); |
392 } | 394 } |
393 | 395 |
394 | 396 |
395 // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" | 397 // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" |
396 int vsskipline(vstr * vs) | 398 int pst_vsskipline(vstr * vs) |
397 { | 399 { |
398 int nloff = find_nl(vs); | 400 int nloff = pst_find_nl(vs); |
399 int nll = skip_nl(vs->b + nloff); | 401 int nll = pst_skip_nl(vs->b + nloff); |
400 | 402 |
401 if (nloff < 0) { | 403 if (nloff < 0) { |
402 //TODO: error | 404 //TODO: error |
403 printf("vb_skipline(): there seems to be no newline here.\n"); | 405 printf("vb_skipline(): there seems to be no newline here.\n"); |
404 return -1; | 406 return -1; |
415 | 417 |
416 return 0; | 418 return 0; |
417 } | 419 } |
418 | 420 |
419 | 421 |
420 int vscatprintf(vstr * vs, char *fmt, ...) | 422 int pst_vscatprintf(vstr * vs, char *fmt, ...) |
421 { | 423 { |
422 int size; | 424 int size; |
423 va_list ap; | 425 va_list ap; |
424 | 426 |
425 /* Guess we need no more than 100 bytes. */ | 427 /* Guess we need no more than 100 bytes. */ |
426 //vsresize( vb, 100 ); | 428 //vsresize( vb, 100 ); |
427 if (!vs->b || vs->dlen == 0) { | 429 if (!vs->b || vs->dlen == 0) { |
428 vsset(vs, ""); | 430 pst_vsset(vs, ""); |
429 } | 431 } |
430 | 432 |
431 while (1) { | 433 while (1) { |
432 /* Try to print in the allocated space. */ | 434 /* Try to print in the allocated space. */ |
433 va_start(ap, fmt); | 435 va_start(ap, fmt); |
439 vs->dlen += size; | 441 vs->dlen += size; |
440 return size; | 442 return size; |
441 } | 443 } |
442 /* Else try again with more space. */ | 444 /* Else try again with more space. */ |
443 if (size >= 0) /* glibc 2.1 */ | 445 if (size >= 0) /* glibc 2.1 */ |
444 vbgrow((vbuf *) vs, size + 1); /* precisely what is needed */ | 446 pst_vbgrow((vbuf *) vs, size + 1); /* precisely what is needed */ |
445 else /* glibc 2.0 */ | 447 else /* glibc 2.0 */ |
446 vbgrow((vbuf *) vs, vs->blen); | 448 pst_vbgrow((vbuf *) vs, vs->blen); |
447 } | 449 } |
448 } | 450 } |
449 | 451 |
450 | 452 |
451 // returns the last character stored in a vstr | 453 // returns the last character stored in a vstr |
452 int vslast(vstr * vs) | 454 int pst_vslast(vstr * vs) |
453 { | 455 { |
454 if (vs->dlen < 1) | 456 if (vs->dlen < 1) |
455 return -1; | 457 return -1; |
456 if (vs->b[vs->dlen - 1] != '\0') | 458 if (vs->b[vs->dlen - 1] != '\0') |
457 return -1; | 459 return -1; |
460 return vs->b[vs->dlen - 2]; | 462 return vs->b[vs->dlen - 2]; |
461 } | 463 } |
462 | 464 |
463 | 465 |
464 // print over vb | 466 // print over vb |
465 void vs_printf(vstr * vs, char *fmt, ...) | 467 void pst_vs_printf(vstr * vs, char *fmt, ...) |
466 { | 468 { |
467 int size; | 469 int size; |
468 va_list ap; | 470 va_list ap; |
469 | 471 |
470 /* Guess we need no more than 100 bytes. */ | 472 /* Guess we need no more than 100 bytes. */ |
471 vbresize((vbuf *) vs, 100); | 473 pst_vbresize((vbuf *) vs, 100); |
472 | 474 |
473 while (1) { | 475 while (1) { |
474 /* Try to print in the allocated space. */ | 476 /* Try to print in the allocated space. */ |
475 va_start(ap, fmt); | 477 va_start(ap, fmt); |
476 size = vsnprintf(vs->b, vs->blen, fmt, ap); | 478 size = vsnprintf(vs->b, vs->blen, fmt, ap); |
481 vs->dlen = size + 1; | 483 vs->dlen = size + 1; |
482 return; | 484 return; |
483 } | 485 } |
484 /* Else try again with more space. */ | 486 /* Else try again with more space. */ |
485 if (size >= 0) /* glibc 2.1 */ | 487 if (size >= 0) /* glibc 2.1 */ |
486 vbresize((vbuf *) vs, size + 1); /* precisely what is needed */ | 488 pst_vbresize((vbuf *) vs, size + 1); /* precisely what is needed */ |
487 else /* glibc 2.0 */ | 489 else /* glibc 2.0 */ |
488 vbresize((vbuf *) vs, vs->blen * 2); | 490 pst_vbresize((vbuf *) vs, vs->blen * 2); |
489 } | 491 } |
490 } | 492 } |
491 | 493 |
492 | 494 |
493 // printf append to vs | 495 // printf append to vs |
494 void vs_printfa(vstr * vs, char *fmt, ...) | 496 void pst_vs_printfa(vstr * vs, char *fmt, ...) |
495 { | 497 { |
496 int size; | 498 int size; |
497 va_list ap; | 499 va_list ap; |
498 | 500 |
499 if (vs->blen - vs->dlen < 50) | 501 if (vs->blen - vs->dlen < 50) |
500 vbgrow((vbuf *) vs, 100); | 502 pst_vbgrow((vbuf *) vs, 100); |
501 | 503 |
502 while (1) { | 504 while (1) { |
503 /* Try to print in the allocated space. */ | 505 /* Try to print in the allocated space. */ |
504 va_start(ap, fmt); | 506 va_start(ap, fmt); |
505 size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap); | 507 size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap); |
510 vs->dlen += size; | 512 vs->dlen += size; |
511 return; | 513 return; |
512 } | 514 } |
513 /* Else try again with more space. */ | 515 /* Else try again with more space. */ |
514 if (size >= 0) /* glibc 2.1 */ | 516 if (size >= 0) /* glibc 2.1 */ |
515 vbgrow((vbuf *) vs, size + 1 - vs->dlen); /* precisely what is needed */ | 517 pst_vbgrow((vbuf *) vs, size + 1 - vs->dlen); /* precisely what is needed */ |
516 else /* glibc 2.0 */ | 518 else /* glibc 2.0 */ |
517 vbgrow((vbuf *) vs, size); | 519 pst_vbgrow((vbuf *) vs, size); |
518 } | 520 } |
519 } | 521 } |
520 | 522 |
521 | 523 |
522 void vshexdump(vstr * vs, const char *b, size_t start, size_t stop, int ascii) | 524 void pst_vshexdump(vstr * vs, const char *b, size_t start, size_t stop, int ascii) |
523 { | 525 { |
524 char c; | 526 char c; |
525 int diff, i; | 527 int diff, i; |
526 | 528 |
527 while (start < stop) { | 529 while (start < stop) { |
528 diff = stop - start; | 530 diff = stop - start; |
529 if (diff > 16) | 531 if (diff > 16) |
530 diff = 16; | 532 diff = 16; |
531 | 533 |
532 vs_printfa(vs, ":%08X ", start); | 534 pst_vs_printfa(vs, ":%08X ", start); |
533 | 535 |
534 for (i = 0; i < diff; i++) { | 536 for (i = 0; i < diff; i++) { |
535 if (8 == i) | 537 if (8 == i) |
536 vs_printfa(vs, " "); | 538 pst_vs_printfa(vs, " "); |
537 vs_printfa(vs, "%02X ", (unsigned char) *(b + start + i)); | 539 pst_vs_printfa(vs, "%02X ", (unsigned char) *(b + start + i)); |
538 } | 540 } |
539 if (ascii) { | 541 if (ascii) { |
540 for (i = diff; i < 16; i++) | 542 for (i = diff; i < 16; i++) |
541 vs_printfa(vs, " "); | 543 pst_vs_printfa(vs, " "); |
542 for (i = 0; i < diff; i++) { | 544 for (i = 0; i < diff; i++) { |
543 c = *(b + start + i); | 545 c = *(b + start + i); |
544 vs_printfa(vs, "%c", isprint(c) ? c : '.'); | 546 pst_vs_printfa(vs, "%c", isprint(c) ? c : '.'); |
545 } | 547 } |
546 } | 548 } |
547 vs_printfa(vs, "\n"); | 549 pst_vs_printfa(vs, "\n"); |
548 start += 16; | 550 start += 16; |
549 } | 551 } |
550 } | 552 } |
551 | 553 |
552 | 554 |
553 void vsset(vstr * vs, char *s) // Store string s in vs | 555 void pst_vsset(vstr * vs, char *s) // Store string s in vs |
554 { | 556 { |
555 vsnset(vs, s, strlen(s)); | 557 pst_vsnset(vs, s, strlen(s)); |
556 } | 558 } |
557 | 559 |
558 | 560 |
559 void vsnset(vstr * vs, char *s, size_t n) // Store string s in vs | 561 void pst_vsnset(vstr * vs, char *s, size_t n) // Store string s in vs |
560 { | 562 { |
561 vbresize((vbuf *) vs, n + 1); | 563 pst_vbresize((vbuf *) vs, n + 1); |
562 memcpy(vs->b, s, n); | 564 memcpy(vs->b, s, n); |
563 vs->b[n] = '\0'; | 565 vs->b[n] = '\0'; |
564 vs->dlen = n + 1; | 566 vs->dlen = n + 1; |
565 } | 567 } |
566 | 568 |
567 | 569 |
568 void vsgrow(vstr * vs, size_t len) // grow buffer by len bytes, data are preserved | 570 void pst_vsgrow(vstr * vs, size_t len) // grow buffer by len bytes, data are preserved |
569 { | 571 { |
570 vbgrow((vbuf *) vs, len); | 572 pst_vbgrow((vbuf *) vs, len); |
571 } | 573 } |
572 | 574 |
573 | 575 |
574 size_t vsavail(vstr * vs) | 576 size_t pst_vsavail(vstr * vs) |
575 { | 577 { |
576 return vbavail((vbuf *) vs); | 578 return pst_vbavail((vbuf *) vs); |
577 } | 579 } |
578 | 580 |
579 | 581 |
580 void vsnset16(vstr * vs, char *s, size_t len) // Like vbstrnset, but for UTF16 | 582 void pst_vsnset16(vstr * vs, char *s, size_t len) // Like vbstrnset, but for UTF16 |
581 { | 583 { |
582 vbresize((vbuf *) vs, len + 1); | 584 pst_vbresize((vbuf *) vs, len + 1); |
583 memcpy(vs->b, s, len); | 585 memcpy(vs->b, s, len); |
584 | 586 |
585 vs->b[len] = '\0'; | 587 vs->b[len] = '\0'; |
586 vs->dlen = len + 1; | 588 vs->dlen = len + 1; |
587 vs->b[len] = '\0'; | 589 vs->b[len] = '\0'; |
588 } | 590 } |
589 | 591 |
590 | 592 |
591 void vscat(vstr * vs, char *str) | 593 void pst_vscat(vstr * vs, char *str) |
592 { | 594 { |
593 vsncat(vs, str, strlen(str)); | 595 pst_vsncat(vs, str, strlen(str)); |
594 } | 596 } |
595 | 597 |
596 | 598 |
597 int vscmp(vstr * vs, char *str) | 599 int pst_vscmp(vstr * vs, char *str) |
598 { | 600 { |
599 return strcmp(vs->b, str); | 601 return strcmp(vs->b, str); |
600 } | 602 } |
601 | 603 |
602 | 604 |
603 void vsncat(vstr * vs, char *str, size_t len) // append string str to vstr, vstr must already contain a valid string | 605 void pst_vsncat(vstr * vs, char *str, size_t len) // append string str to vstr, vstr must already contain a valid string |
604 { | 606 { |
605 ASSERT(vs->b[vs->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string."); | 607 ASSERT(vs->b[vs->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string."); |
606 size_t sl = strlen(str); | 608 size_t sl = strlen(str); |
607 size_t n = (sl < len) ? sl : len; | 609 size_t n = (sl < len) ? sl : len; |
608 //string append | 610 //string append |
609 vbgrow((vbuf *) vs, n + 1); | 611 pst_vbgrow((vbuf *) vs, n + 1); |
610 memcpy(vs->b + vs->dlen - 1, str, n); | 612 memcpy(vs->b + vs->dlen - 1, str, n); |
611 vs->dlen += n; | 613 vs->dlen += n; |
612 vs->b[vs->dlen - 1] = '\0'; | 614 vs->b[vs->dlen - 1] = '\0'; |
613 } | 615 } |
614 | 616 |
615 | 617 |
616 void vstrunc(vstr * v, size_t off) // Drop chars [off..dlen] | 618 void pst_vstrunc(vstr * v, size_t off) // Drop chars [off..dlen] |
617 { | 619 { |
618 if (off >= v->dlen - 1) | 620 if (off >= v->dlen - 1) |
619 return; //nothing to do | 621 return; //nothing to do |
620 v->b[off] = '\0'; | 622 v->b[off] = '\0'; |
621 v->dlen = off + 1; | 623 v->dlen = off + 1; |