Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Simple string buffer
4 : *
5 : * Copyright (C) 2017 Christian Franke
6 : */
7 : #include <zebra.h>
8 :
9 : #include "printfrr.h"
10 : #include "sbuf.h"
11 : #include "memory.h"
12 :
13 0 : void sbuf_init(struct sbuf *dest, char *buf, size_t size)
14 : {
15 0 : dest->fixed = (size > 0);
16 0 : if (dest->fixed) {
17 0 : dest->buf = buf;
18 0 : dest->size = size;
19 : } else {
20 0 : dest->buf = XMALLOC(MTYPE_TMP, SBUF_DEFAULT_SIZE);
21 0 : dest->size = SBUF_DEFAULT_SIZE;
22 : }
23 :
24 0 : dest->pos = 0;
25 0 : dest->buf[0] = '\0';
26 0 : }
27 :
28 0 : void sbuf_reset(struct sbuf *dest)
29 : {
30 0 : dest->pos = 0;
31 0 : dest->buf[0] = '\0';
32 0 : }
33 :
34 0 : const char *sbuf_buf(struct sbuf *buf)
35 : {
36 0 : return buf->buf;
37 : }
38 :
39 0 : void sbuf_free(struct sbuf *buf)
40 : {
41 0 : if (!buf->fixed)
42 0 : XFREE(MTYPE_TMP, buf->buf);
43 0 : }
44 :
45 0 : void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
46 : {
47 0 : va_list args;
48 0 : int written;
49 :
50 0 : if (!buf->fixed) {
51 0 : int written1, written2;
52 0 : size_t new_size;
53 :
54 0 : written1 = indent;
55 0 : va_start(args, format);
56 0 : written2 = vsnprintfrr(NULL, 0, format, args);
57 0 : va_end(args);
58 :
59 0 : new_size = buf->size;
60 0 : if (written1 >= 0 && written2 >= 0) {
61 0 : while (buf->pos + written1 + written2 >= new_size)
62 0 : new_size *= 2;
63 0 : if (new_size > buf->size) {
64 0 : buf->buf =
65 0 : XREALLOC(MTYPE_TMP, buf->buf, new_size);
66 0 : buf->size = new_size;
67 : }
68 : }
69 : }
70 :
71 0 : written = snprintf(buf->buf + buf->pos, buf->size - buf->pos, "%*s",
72 : indent, "");
73 :
74 0 : if (written >= 0)
75 0 : buf->pos += written;
76 0 : if (buf->pos > buf->size)
77 0 : buf->pos = buf->size;
78 :
79 0 : va_start(args, format);
80 0 : written = vsnprintfrr(buf->buf + buf->pos, buf->size - buf->pos,
81 : format, args);
82 0 : va_end(args);
83 :
84 0 : if (written >= 0)
85 0 : buf->pos += written;
86 0 : if (buf->pos > buf->size)
87 0 : buf->pos = buf->size;
88 :
89 0 : if (buf->pos == buf->size)
90 0 : assert(!"Buffer filled up!");
91 0 : }
|