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