]> git.proxmox.com Git - mirror_frr.git/blob - lib/sbuf.c
Merge pull request #13278 from FRRouting/mergify/bp/stable/8.5/pr-13269
[mirror_frr.git] / lib / sbuf.c
1 /*
2 * Simple string buffer
3 *
4 * Copyright (C) 2017 Christian Franke
5 *
6 * This file is part of FRR.
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with FRR; see the file COPYING. If not, write to the Free
20 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA.
22 */
23 #include <zebra.h>
24
25 #include "printfrr.h"
26 #include "sbuf.h"
27 #include "memory.h"
28
29 void sbuf_init(struct sbuf *dest, char *buf, size_t size)
30 {
31 dest->fixed = (size > 0);
32 if (dest->fixed) {
33 dest->buf = buf;
34 dest->size = size;
35 } else {
36 dest->buf = XMALLOC(MTYPE_TMP, 4096);
37 dest->size = 4096;
38 }
39
40 dest->pos = 0;
41 dest->buf[0] = '\0';
42 }
43
44 void sbuf_reset(struct sbuf *dest)
45 {
46 dest->pos = 0;
47 dest->buf[0] = '\0';
48 }
49
50 const char *sbuf_buf(struct sbuf *buf)
51 {
52 return buf->buf;
53 }
54
55 void sbuf_free(struct sbuf *buf)
56 {
57 if (!buf->fixed)
58 XFREE(MTYPE_TMP, buf->buf);
59 }
60
61 void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
62 {
63 va_list args;
64 int written;
65
66 if (!buf->fixed) {
67 int written1, written2;
68 size_t new_size;
69
70 written1 = indent;
71 va_start(args, format);
72 written2 = vsnprintfrr(NULL, 0, format, args);
73 va_end(args);
74
75 new_size = buf->size;
76 if (written1 >= 0 && written2 >= 0) {
77 while (buf->pos + written1 + written2 >= new_size)
78 new_size *= 2;
79 if (new_size > buf->size) {
80 buf->buf =
81 XREALLOC(MTYPE_TMP, buf->buf, new_size);
82 buf->size = new_size;
83 }
84 }
85 }
86
87 written = snprintf(buf->buf + buf->pos, buf->size - buf->pos, "%*s",
88 indent, "");
89
90 if (written >= 0)
91 buf->pos += written;
92 if (buf->pos > buf->size)
93 buf->pos = buf->size;
94
95 va_start(args, format);
96 written = vsnprintfrr(buf->buf + buf->pos, buf->size - buf->pos,
97 format, args);
98 va_end(args);
99
100 if (written >= 0)
101 buf->pos += written;
102 if (buf->pos > buf->size)
103 buf->pos = buf->size;
104
105 if (buf->pos == buf->size)
106 assert(!"Buffer filled up!");
107 }