Postfix3.3.1
vstring.c
[詳解]
1 /*++
2 /* NAME
3 /* vstring 3
4 /* SUMMARY
5 /* arbitrary-length string manager
6 /* SYNOPSIS
7 /* #include <vstring.h>
8 /*
9 /* VSTRING *vstring_alloc(len)
10 /* ssize_t len;
11 /*
12 /* vstring_ctl(vp, type, value, ..., VSTRING_CTL_END)
13 /* VSTRING *vp;
14 /* int type;
15 /*
16 /* VSTRING *vstring_free(vp)
17 /* VSTRING *vp;
18 /*
19 /* char *vstring_str(vp)
20 /* VSTRING *vp;
21 /*
22 /* ssize_t VSTRING_LEN(vp)
23 /* VSTRING *vp;
24 /*
25 /* char *vstring_end(vp)
26 /* VSTRING *vp;
27 /*
28 /* void VSTRING_ADDCH(vp, ch)
29 /* VSTRING *vp;
30 /* int ch;
31 /*
32 /* int VSTRING_SPACE(vp, len)
33 /* VSTRING *vp;
34 /* ssize_t len;
35 /*
36 /* ssize_t vstring_avail(vp)
37 /* VSTRING *vp;
38 /*
39 /* VSTRING *vstring_truncate(vp, len)
40 /* VSTRING *vp;
41 /* ssize_t len;
42 /*
43 /* void VSTRING_RESET(vp)
44 /* VSTRING *vp;
45 /*
46 /* void VSTRING_TERMINATE(vp)
47 /* VSTRING *vp;
48 /*
49 /* void VSTRING_SKIP(vp)
50 /* VSTRING *vp;
51 /*
52 /* VSTRING *vstring_strcpy(vp, src)
53 /* VSTRING *vp;
54 /* const char *src;
55 /*
56 /* VSTRING *vstring_strncpy(vp, src, len)
57 /* VSTRING *vp;
58 /* const char *src;
59 /* ssize_t len;
60 /*
61 /* VSTRING *vstring_strcat(vp, src)
62 /* VSTRING *vp;
63 /* const char *src;
64 /*
65 /* VSTRING *vstring_strncat(vp, src, len)
66 /* VSTRING *vp;
67 /* const char *src;
68 /* ssize_t len;
69 /*
70 /* VSTRING *vstring_memcpy(vp, src, len)
71 /* VSTRING *vp;
72 /* const char *src;
73 /* ssize_t len;
74 /*
75 /* VSTRING *vstring_memcat(vp, src, len)
76 /* VSTRING *vp;
77 /* const char *src;
78 /* ssize_t len;
79 /*
80 /* char *vstring_memchr(vp, ch)
81 /* VSTRING *vp;
82 /* int ch;
83 /*
84 /* VSTRING *vstring_insert(vp, start, src, len)
85 /* VSTRING *vp;
86 /* ssize_t start;
87 /* const char *src;
88 /* ssize_t len;
89 /*
90 /* VSTRING *vstring_prepend(vp, src, len)
91 /* VSTRING *vp;
92 /* const char *src;
93 /* ssize_t len;
94 /*
95 /* VSTRING *vstring_sprintf(vp, format, ...)
96 /* VSTRING *vp;
97 /* const char *format;
98 /*
99 /* VSTRING *vstring_sprintf_append(vp, format, ...)
100 /* VSTRING *vp;
101 /* const char *format;
102 /*
103 /* VSTRING *vstring_sprintf_prepend(vp, format, ...)
104 /* VSTRING *vp;
105 /* const char *format;
106 /*
107 /* VSTRING *vstring_vsprintf(vp, format, ap)
108 /* VSTRING *vp;
109 /* const char *format;
110 /* va_list ap;
111 /*
112 /* VSTRING *vstring_vsprintf_append(vp, format, ap)
113 /* VSTRING *vp;
114 /* const char *format;
115 /* va_list ap;
116 /* AUXILIARY FUNCTIONS
117 /* char *vstring_export(vp)
118 /* VSTRING *vp;
119 /*
120 /* VSTRING *vstring_import(str)
121 /* char *str;
122 /* DESCRIPTION
123 /* The functions and macros in this module implement arbitrary-length
124 /* strings and common operations on those strings. The strings do not
125 /* need to be null terminated and may contain arbitrary binary data.
126 /* The strings manage their own memory and grow automatically when full.
127 /* The optional string null terminator does not add to the string length.
128 /*
129 /* vstring_alloc() allocates storage for a variable-length string
130 /* of at least "len" bytes. The minimal length is 1. The result
131 /* is a null-terminated string of length zero.
132 /*
133 /* vstring_ctl() gives additional control over VSTRING behavior.
134 /* The function takes a VSTRING pointer and a list of zero or
135 /* more macros with zer or more arguments, terminated with
136 /* CA_VSTRING_CTL_END which has none.
137 /* .IP "CA_VSTRING_CTL_MAXLEN(ssize_t len)"
138 /* Specifies a hard upper limit on a string's length. When the
139 /* length would be exceeded, the program simulates a memory
140 /* allocation problem (i.e. it terminates through msg_fatal()).
141 /* This fuctionality is currently unimplemented.
142 /* .IP "CA_VSTRING_CTL_EXACT (no argument)"
143 /* Allocate the requested amounts, instead of rounding up.
144 /* This should be used for tests only.
145 /* .IP "CA_VSTRING_CTL_END (no argument)"
146 /* Specifies the end of the argument list. Forgetting to terminate
147 /* the argument list may cause the program to crash.
148 /* .PP
149 /* VSTRING_SPACE() ensures that the named string has room for
150 /* "len" more characters. VSTRING_SPACE() is an unsafe macro
151 /* that either returns zero or never returns.
152 /*
153 /* vstring_avail() returns the number of bytes that can be placed
154 /* into the buffer before the buffer would need to grow.
155 /*
156 /* vstring_free() reclaims storage for a variable-length string.
157 /* It conveniently returns a null pointer.
158 /*
159 /* vstring_str() is a macro that returns the string value
160 /* of a variable-length string. It is a safe macro that
161 /* evaluates its argument only once.
162 /*
163 /* VSTRING_LEN() is a macro that returns the current length of
164 /* its argument (i.e. the distance from the start of the string
165 /* to the current write position). VSTRING_LEN() is an unsafe macro
166 /* that evaluates its argument more than once.
167 /*
168 /* vstring_end() is a macro that returns the current write position of
169 /* its argument. It is a safe macro that evaluates its argument only once.
170 /*
171 /* VSTRING_ADDCH() adds a character to a variable-length string
172 /* and extends the string if it fills up. \fIvs\fP is a pointer
173 /* to a VSTRING structure; \fIch\fP the character value to be written.
174 /* The result is the written character.
175 /* Note that VSTRING_ADDCH() is an unsafe macro that evaluates some
176 /* arguments more than once. The result is NOT null-terminated.
177 /*
178 /* vstring_truncate() truncates the named string to the specified
179 /* length. If length is negative, the trailing portion is kept.
180 /* The operation has no effect when the string is shorter.
181 /* The string is not null-terminated.
182 /*
183 /* VSTRING_RESET() is a macro that resets the write position of its
184 /* string argument to the very beginning. Note that VSTRING_RESET()
185 /* is an unsafe macro that evaluates some arguments more than once.
186 /* The result is NOT null-terminated.
187 /*
188 /* VSTRING_TERMINATE() null-terminates its string argument.
189 /* VSTRING_TERMINATE() is an unsafe macro that evaluates some
190 /* arguments more than once.
191 /* VSTRING_TERMINATE() does not return an interesting result.
192 /*
193 /* VSTRING_SKIP() is a macro that moves the write position to the first
194 /* null byte after the current write position. VSTRING_SKIP() is an unsafe
195 /* macro that evaluates some arguments more than once.
196 /*
197 /* vstring_strcpy() copies a null-terminated string to a variable-length
198 /* string. \fIsrc\fP provides the data to be copied; \fIvp\fP is the
199 /* target and result value. The result is null-terminated.
200 /*
201 /* vstring_strncpy() copies at most \fIlen\fR characters. Otherwise it is
202 /* identical to vstring_strcpy().
203 /*
204 /* vstring_strcat() appends a null-terminated string to a variable-length
205 /* string. \fIsrc\fP provides the data to be copied; \fIvp\fP is the
206 /* target and result value. The result is null-terminated.
207 /*
208 /* vstring_strncat() copies at most \fIlen\fR characters. Otherwise it is
209 /* identical to vstring_strcat().
210 /*
211 /* vstring_memcpy() copies \fIlen\fR bytes to a variable-length string.
212 /* \fIsrc\fP provides the data to be copied; \fIvp\fP is the
213 /* target and result value. The result is not null-terminated.
214 /*
215 /* vstring_memcat() appends \fIlen\fR bytes to a variable-length string.
216 /* \fIsrc\fP provides the data to be copied; \fIvp\fP is the
217 /* target and result value. The result is not null-terminated.
218 /*
219 /* vstring_memchr() locates a byte in a variable-length string.
220 /*
221 /* vstring_insert() inserts a buffer content into a variable-length
222 /* string at the specified start position. The result is
223 /* null-terminated.
224 /*
225 /* vstring_prepend() prepends a buffer content to a variable-length
226 /* string. The result is null-terminated.
227 /*
228 /* vstring_sprintf() produces a formatted string according to its
229 /* \fIformat\fR argument. See vstring_vsprintf() for details.
230 /*
231 /* vstring_sprintf_append() is like vstring_sprintf(), but appends
232 /* to the end of the result buffer.
233 /*
234 /* vstring_sprintf_append() is like vstring_sprintf(), but prepends
235 /* to the beginning of the result buffer.
236 /*
237 /* vstring_vsprintf() returns a null-terminated string according to
238 /* the \fIformat\fR argument. It understands the s, c, d, u,
239 /* o, x, X, p, e, f and g format types, the l modifier, field width
240 /* and precision, sign, and null or space padding. This module
241 /* can format strings as large as available memory permits.
242 /*
243 /* vstring_vsprintf_append() is like vstring_vsprintf(), but appends
244 /* to the end of the result buffer.
245 /*
246 /* In addition to stdio-like format specifiers, vstring_vsprintf()
247 /* recognizes %m and expands it to the corresponding errno text.
248 /*
249 /* vstring_export() extracts the string value from a VSTRING.
250 /* The VSTRING is destroyed. The result should be passed to myfree().
251 /*
252 /* vstring_import() takes a `bare' string and converts it to
253 /* a VSTRING. The string argument must be obtained from mymalloc().
254 /* The string argument is not copied.
255 /* DIAGNOSTICS
256 /* Fatal errors: memory allocation failure.
257 /* BUGS
258 /* Auto-resizing may change the address of the string data in
259 /* a vstring structure. Beware of dangling pointers.
260 /* HISTORY
261 /* .ad
262 /* .fi
263 /* A vstring module appears in the UNPROTO software by Wietse Venema.
264 /* AUTHOR(S)
265 /* Wietse Venema
266 /* IBM T.J. Watson Research
267 /* P.O. Box 704
268 /* Yorktown Heights, NY 10598, USA
269 /*
270 /* Wietse Venema
271 /* Google, Inc.
272 /* 111 8th Avenue
273 /* New York, NY 10011, USA
274 /*--*/
275 
276 /* System libraries. */
277 
278 #include <sys_defs.h>
279 #include <stddef.h>
280 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
281 #include <stdarg.h>
282 #include <string.h>
283 
284 /* Utility library. */
285 
286 #include "mymalloc.h"
287 #include "msg.h"
288 #include "vbuf_print.h"
289 #include "vstring.h"
290 
291 /* vstring_extend - variable-length string buffer extension policy */
292 
293 static void vstring_extend(VBUF *bp, ssize_t incr)
294 {
295  size_t used = bp->ptr - bp->data;
296  ssize_t new_len;
297 
298  /*
299  * Note: vp->vbuf.len is the current buffer size (both on entry and on
300  * exit of this routine). We round up the increment size to the buffer
301  * size to avoid silly little buffer increments. With really large
302  * strings we might want to abandon the length doubling strategy, and go
303  * to fixed increments.
304  *
305  * The length overflow tests here and in vstring_alloc() should protect us
306  * against all length overflow problems within vstring library routines.
307  *
308  * Safety net: add a gratuitous null terminator so that C-style string
309  * operations won't scribble past the end.
310  */
311  if ((bp->flags & VSTRING_FLAG_EXACT) == 0 && bp->len > incr)
312  incr = bp->len;
313  if (bp->len > SSIZE_T_MAX - incr - 1)
314  msg_fatal("vstring_extend: length overflow");
315  new_len = bp->len + incr;
316  bp->data = (unsigned char *) myrealloc((void *) bp->data, new_len + 1);
317  bp->data[new_len] = 0;
318  bp->len = new_len;
319  bp->ptr = bp->data + used;
320  bp->cnt = bp->len - used;
321 }
322 
323 /* vstring_buf_get_ready - vbuf callback for read buffer empty condition */
324 
325 static int vstring_buf_get_ready(VBUF *unused_buf)
326 {
327  msg_panic("vstring_buf_get: write-only buffer");
328 }
329 
330 /* vstring_buf_put_ready - vbuf callback for write buffer full condition */
331 
332 static int vstring_buf_put_ready(VBUF *bp)
333 {
334  vstring_extend(bp, 1);
335  return (0);
336 }
337 
338 /* vstring_buf_space - vbuf callback to reserve space */
339 
340 static int vstring_buf_space(VBUF *bp, ssize_t len)
341 {
342  ssize_t need;
343 
344  if (len < 0)
345  msg_panic("vstring_buf_space: bad length %ld", (long) len);
346  if ((need = len - bp->cnt) > 0)
347  vstring_extend(bp, need);
348  return (0);
349 }
350 
351 /* vstring_alloc - create variable-length string */
352 
353 VSTRING *vstring_alloc(ssize_t len)
354 {
355  VSTRING *vp;
356 
357  /*
358  * Safety net: add a gratuitous null terminator so that C-style string
359  * operations won't scribble past the end.
360  */
361  if (len < 1 || len > SSIZE_T_MAX - 1)
362  msg_panic("vstring_alloc: bad length %ld", (long) len);
363  vp = (VSTRING *) mymalloc(sizeof(*vp));
364  vp->vbuf.flags = 0;
365  vp->vbuf.len = 0;
366  vp->vbuf.data = (unsigned char *) mymalloc(len + 1);
367  vp->vbuf.data[len] = 0;
368  vp->vbuf.len = len;
369  VSTRING_RESET(vp);
370  vp->vbuf.data[0] = 0;
371  vp->vbuf.get_ready = vstring_buf_get_ready;
372  vp->vbuf.put_ready = vstring_buf_put_ready;
373  vp->vbuf.space = vstring_buf_space;
374  vp->maxlen = 0;
375  return (vp);
376 }
377 
378 /* vstring_free - destroy variable-length string */
379 
381 {
382  if (vp->vbuf.data)
383  myfree((void *) vp->vbuf.data);
384  myfree((void *) vp);
385  return (0);
386 }
387 
388 /* vstring_ctl - modify memory management policy */
389 
390 void vstring_ctl(VSTRING *vp,...)
391 {
392  va_list ap;
393  int code;
394 
395  va_start(ap, vp);
396  while ((code = va_arg(ap, int)) != VSTRING_CTL_END) {
397  switch (code) {
398  default:
399  msg_panic("vstring_ctl: unknown code: %d", code);
400  case VSTRING_CTL_MAXLEN:
401  vp->maxlen = va_arg(ap, ssize_t);
402  if (vp->maxlen < 0)
403  msg_panic("vstring_ctl: bad max length %ld", (long) vp->maxlen);
404  break;
405  case VSTRING_CTL_EXACT:
407  break;
408  }
409  }
410  va_end(ap);
411 }
412 
413 /* vstring_truncate - truncate string */
414 
415 VSTRING *vstring_truncate(VSTRING *vp, ssize_t len)
416 {
417  ssize_t move;
418 
419  if (len < 0) {
420  len = (-len);
421  if ((move = VSTRING_LEN(vp) - len) > 0)
422  memmove(vstring_str(vp), vstring_str(vp) + move, len);
423  }
424  if (len < VSTRING_LEN(vp))
425  VSTRING_AT_OFFSET(vp, len);
426  return (vp);
427 }
428 
429 /* vstring_strcpy - copy string */
430 
431 VSTRING *vstring_strcpy(VSTRING *vp, const char *src)
432 {
433  VSTRING_RESET(vp);
434 
435  while (*src) {
436  VSTRING_ADDCH(vp, *src);
437  src++;
438  }
439  VSTRING_TERMINATE(vp);
440  return (vp);
441 }
442 
443 /* vstring_strncpy - copy string of limited length */
444 
445 VSTRING *vstring_strncpy(VSTRING *vp, const char *src, ssize_t len)
446 {
447  VSTRING_RESET(vp);
448 
449  while (len-- > 0 && *src) {
450  VSTRING_ADDCH(vp, *src);
451  src++;
452  }
453  VSTRING_TERMINATE(vp);
454  return (vp);
455 }
456 
457 /* vstring_strcat - append string */
458 
459 VSTRING *vstring_strcat(VSTRING *vp, const char *src)
460 {
461  while (*src) {
462  VSTRING_ADDCH(vp, *src);
463  src++;
464  }
465  VSTRING_TERMINATE(vp);
466  return (vp);
467 }
468 
469 /* vstring_strncat - append string of limited length */
470 
471 VSTRING *vstring_strncat(VSTRING *vp, const char *src, ssize_t len)
472 {
473  while (len-- > 0 && *src) {
474  VSTRING_ADDCH(vp, *src);
475  src++;
476  }
477  VSTRING_TERMINATE(vp);
478  return (vp);
479 }
480 
481 /* vstring_memcpy - copy buffer of limited length */
482 
483 VSTRING *vstring_memcpy(VSTRING *vp, const char *src, ssize_t len)
484 {
485  VSTRING_RESET(vp);
486 
487  VSTRING_SPACE(vp, len);
488  memcpy(vstring_str(vp), src, len);
489  VSTRING_AT_OFFSET(vp, len);
490  return (vp);
491 }
492 
493 /* vstring_memcat - append buffer of limited length */
494 
495 VSTRING *vstring_memcat(VSTRING *vp, const char *src, ssize_t len)
496 {
497  VSTRING_SPACE(vp, len);
498  memcpy(vstring_end(vp), src, len);
499  len += VSTRING_LEN(vp);
500  VSTRING_AT_OFFSET(vp, len);
501  return (vp);
502 }
503 
504 /* vstring_memchr - locate byte in buffer */
505 
506 char *vstring_memchr(VSTRING *vp, int ch)
507 {
508  unsigned char *cp;
509 
510  for (cp = (unsigned char *) vstring_str(vp); cp < (unsigned char *) vstring_end(vp); cp++)
511  if (*cp == ch)
512  return ((char *) cp);
513  return (0);
514 }
515 
516 /* vstring_insert - insert text into string */
517 
518 VSTRING *vstring_insert(VSTRING *vp, ssize_t start, const char *buf, ssize_t len)
519 {
520  ssize_t new_len;
521 
522  /*
523  * Sanity check.
524  */
525  if (start < 0 || start >= VSTRING_LEN(vp))
526  msg_panic("vstring_insert: bad start %ld", (long) start);
527  if (len < 0)
528  msg_panic("vstring_insert: bad length %ld", (long) len);
529 
530  /*
531  * Move the existing content and copy the new content.
532  */
533  new_len = VSTRING_LEN(vp) + len;
534  VSTRING_SPACE(vp, len);
535  memmove(vstring_str(vp) + start + len, vstring_str(vp) + start,
536  VSTRING_LEN(vp) - start);
537  memcpy(vstring_str(vp) + start, buf, len);
538  VSTRING_AT_OFFSET(vp, new_len);
539  VSTRING_TERMINATE(vp);
540  return (vp);
541 }
542 
543 /* vstring_prepend - prepend text to string */
544 
545 VSTRING *vstring_prepend(VSTRING *vp, const char *buf, ssize_t len)
546 {
547  ssize_t new_len;
548 
549  /*
550  * Sanity check.
551  */
552  if (len < 0)
553  msg_panic("vstring_prepend: bad length %ld", (long) len);
554 
555  /*
556  * Move the existing content and copy the new content.
557  */
558  new_len = VSTRING_LEN(vp) + len;
559  VSTRING_SPACE(vp, len);
560  memmove(vstring_str(vp) + len, vstring_str(vp), VSTRING_LEN(vp));
561  memcpy(vstring_str(vp), buf, len);
562  VSTRING_AT_OFFSET(vp, new_len);
563  VSTRING_TERMINATE(vp);
564  return (vp);
565 }
566 
567 /* vstring_export - VSTRING to bare string */
568 
570 {
571  char *cp;
572 
573  cp = (char *) vp->vbuf.data;
574  vp->vbuf.data = 0;
575  myfree((void *) vp);
576  return (cp);
577 }
578 
579 /* vstring_import - bare string to vstring */
580 
582 {
583  VSTRING *vp;
584  ssize_t len;
585 
586  vp = (VSTRING *) mymalloc(sizeof(*vp));
587  len = strlen(str);
588  vp->vbuf.flags = 0;
589  vp->vbuf.len = 0;
590  vp->vbuf.data = (unsigned char *) str;
591  vp->vbuf.len = len + 1;
592  VSTRING_AT_OFFSET(vp, len);
593  vp->vbuf.get_ready = vstring_buf_get_ready;
594  vp->vbuf.put_ready = vstring_buf_put_ready;
595  vp->vbuf.space = vstring_buf_space;
596  vp->maxlen = 0;
597  return (vp);
598 }
599 
600 /* vstring_sprintf - formatted string */
601 
602 VSTRING *vstring_sprintf(VSTRING *vp, const char *format,...)
603 {
604  va_list ap;
605 
606  va_start(ap, format);
607  vp = vstring_vsprintf(vp, format, ap);
608  va_end(ap);
609  return (vp);
610 }
611 
612 /* vstring_vsprintf - format string, vsprintf-like interface */
613 
614 VSTRING *vstring_vsprintf(VSTRING *vp, const char *format, va_list ap)
615 {
616  VSTRING_RESET(vp);
617  vbuf_print(&vp->vbuf, format, ap);
618  VSTRING_TERMINATE(vp);
619  return (vp);
620 }
621 
622 /* vstring_sprintf_append - append formatted string */
623 
624 VSTRING *vstring_sprintf_append(VSTRING *vp, const char *format,...)
625 {
626  va_list ap;
627 
628  va_start(ap, format);
629  vp = vstring_vsprintf_append(vp, format, ap);
630  va_end(ap);
631  return (vp);
632 }
633 
634 /* vstring_vsprintf_append - format + append string, vsprintf-like interface */
635 
636 VSTRING *vstring_vsprintf_append(VSTRING *vp, const char *format, va_list ap)
637 {
638  vbuf_print(&vp->vbuf, format, ap);
639  VSTRING_TERMINATE(vp);
640  return (vp);
641 }
642 
643 /* vstring_sprintf_prepend - format + prepend string, vsprintf-like interface */
644 
645 VSTRING *vstring_sprintf_prepend(VSTRING *vp, const char *format,...)
646 {
647  va_list ap;
648  ssize_t old_len = VSTRING_LEN(vp);
649  ssize_t result_len;
650 
651  /* Construct: old|new|free */
652  va_start(ap, format);
653  vp = vstring_vsprintf_append(vp, format, ap);
654  va_end(ap);
655  result_len = VSTRING_LEN(vp);
656 
657  /* Construct: old|new|old|free */
658  VSTRING_SPACE(vp, old_len);
659  vstring_memcat(vp, vstring_str(vp), old_len);
660 
661  /* Construct: new|old|free */
662  memmove(vstring_str(vp), vstring_str(vp) + old_len, result_len);
663  VSTRING_AT_OFFSET(vp, result_len);
664  VSTRING_TERMINATE(vp);
665  return (vp);
666 }
667 
668 #ifdef TEST
669 
670  /*
671  * Test program - concatenate all command-line arguments into one string.
672  */
673 #include <stdio.h>
674 
675 int main(int argc, char **argv)
676 {
677  VSTRING *vp = vstring_alloc(1);
678  int n;
679 
680  /*
681  * Report the location of the gratuitous null terminator.
682  */
683  for (n = 1; n <= 5; n++) {
684  VSTRING_ADDCH(vp, 'x');
685  printf("payload/buffer size %d/%ld, strlen() %ld\n",
686  n, (long) (vp)->vbuf.len, (long) strlen(vstring_str(vp)));
687  }
688 
689  VSTRING_RESET(vp);
690  while (argc-- > 0) {
691  vstring_strcat(vp, *argv++);
692  vstring_strcat(vp, ".");
693  }
694  printf("argv concatenated: %s\n", vstring_str(vp));
695  vstring_free(vp);
696  return (0);
697 }
698 
699 #endif
void myfree(void *ptr)
Definition: mymalloc.c:207
VSTRING * vstring_sprintf_prepend(VSTRING *vp, const char *format,...)
Definition: vstring.c:645
VBUF_GET_READY_FN get_ready
Definition: vbuf.h:43
ssize_t cnt
Definition: vbuf.h:41
unsigned char * ptr
Definition: vbuf.h:42
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define vstring_str(vp)
Definition: vstring.h:71
void * myrealloc(void *ptr, ssize_t len)
Definition: mymalloc.c:175
int main(int argc, char **argv)
Definition: anvil.c:1010
VSTRING * vstring_strncat(VSTRING *vp, const char *src, ssize_t len)
Definition: vstring.c:471
VSTRING * vstring_truncate(VSTRING *vp, ssize_t len)
Definition: vstring.c:415
#define VSTRING_LEN(vp)
Definition: vstring.h:72
void vstring_ctl(VSTRING *vp,...)
Definition: vstring.c:390
unsigned char * data
Definition: vbuf.h:39
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
#define VSTRING_TERMINATE(vp)
Definition: vstring.h:74
#define vstring_end(vp)
Definition: vstring.h:73
VSTRING * vstring_prepend(VSTRING *vp, const char *buf, ssize_t len)
Definition: vstring.c:545
VSTRING * vstring_insert(VSTRING *vp, ssize_t start, const char *buf, ssize_t len)
Definition: vstring.c:518
#define VSTRING_ADDCH(vp, ch)
Definition: vstring.h:81
VSTRING * vstring_sprintf_append(VSTRING *vp, const char *format,...)
Definition: vstring.c:624
VSTRING * vstring_vsprintf(VSTRING *vp, const char *format, va_list ap)
Definition: vstring.c:614
#define VSTRING_RESET(vp)
Definition: vstring.h:77
int flags
Definition: vbuf.h:38
Definition: vbuf.h:37
#define VSTRING_FLAG_EXACT
Definition: vstring.h:65
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
ssize_t maxlen
Definition: vstring.h:31
VBUF vbuf
Definition: vstring.h:30
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
Definition: vstring.c:602
VBUF_SPACE_FN space
Definition: vbuf.h:45
#define VSTRING_CTL_MAXLEN
Definition: vstring.h:54
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
VSTRING * vstring_memcat(VSTRING *vp, const char *src, ssize_t len)
Definition: vstring.c:495
VBUF_PUT_READY_FN put_ready
Definition: vbuf.h:44
VBUF * vbuf_print(VBUF *bp, const char *format, va_list ap)
Definition: vbuf_print.c:147
#define VSTRING_SPACE(vp, len)
Definition: vstring.h:70
#define SSIZE_T_MAX
Definition: sys_defs.h:1687
#define VSTRING_CTL_END
Definition: vstring.h:56
VSTRING * vstring_vsprintf_append(VSTRING *vp, const char *format, va_list ap)
Definition: vstring.c:636
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
ssize_t len
Definition: vbuf.h:40
#define VSTRING_AT_OFFSET(vp, offset)
Definition: vstring.h:92
#define VSTRING_CTL_EXACT
Definition: vstring.h:55
VSTRING * vstring_memcpy(VSTRING *vp, const char *src, ssize_t len)
Definition: vstring.c:483
VSTRING * vstring_import(char *str)
Definition: vstring.c:581
char * vstring_memchr(VSTRING *vp, int ch)
Definition: vstring.c:506
VSTRING * vstring_strncpy(VSTRING *vp, const char *src, ssize_t len)
Definition: vstring.c:445
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
Definition: vstring.c:459
char * vstring_export(VSTRING *vp)
Definition: vstring.c:569
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150