Line | Count | Source (jump to first uncovered line) |
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 | | void sbuf_init(struct sbuf *dest, char *buf, size_t size) |
14 | 0 | { |
15 | 0 | dest->fixed = (size > 0); |
16 | 0 | if (dest->fixed) { |
17 | 0 | dest->buf = buf; |
18 | 0 | dest->size = size; |
19 | 0 | } else { |
20 | 0 | dest->buf = XMALLOC(MTYPE_TMP, SBUF_DEFAULT_SIZE); |
21 | 0 | dest->size = SBUF_DEFAULT_SIZE; |
22 | 0 | } |
23 | |
|
24 | 0 | dest->pos = 0; |
25 | 0 | dest->buf[0] = '\0'; |
26 | 0 | } |
27 | | |
28 | | void sbuf_reset(struct sbuf *dest) |
29 | 0 | { |
30 | 0 | dest->pos = 0; |
31 | 0 | dest->buf[0] = '\0'; |
32 | 0 | } |
33 | | |
34 | | const char *sbuf_buf(struct sbuf *buf) |
35 | 0 | { |
36 | 0 | return buf->buf; |
37 | 0 | } |
38 | | |
39 | | void sbuf_free(struct sbuf *buf) |
40 | 0 | { |
41 | 0 | if (!buf->fixed) |
42 | 0 | XFREE(MTYPE_TMP, buf->buf); |
43 | 0 | } |
44 | | |
45 | | void sbuf_push(struct sbuf *buf, int indent, const char *format, ...) |
46 | 0 | { |
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 | 0 | } |
68 | 0 | } |
69 | 0 | } |
70 | |
|
71 | 0 | written = snprintf(buf->buf + buf->pos, buf->size - buf->pos, "%*s", |
72 | 0 | 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 | 0 | 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 | } |