]> git.proxmox.com Git - mirror_frr.git/blob - lib/sbuf.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[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 "sbuf.h"
26 #include "memory.h"
27
28 void sbuf_init(struct sbuf *dest, char *buf, size_t size)
29 {
30 dest->fixed = (size > 0);
31 if (dest->fixed) {
32 dest->buf = buf;
33 dest->size = size;
34 } else {
35 dest->buf = XMALLOC(MTYPE_TMP, 4096);
36 dest->size = 4096;
37 }
38
39 dest->pos = 0;
40 dest->buf[0] = '\0';
41 }
42
43 void sbuf_reset(struct sbuf *dest)
44 {
45 dest->pos = 0;
46 dest->buf[0] = '\0';
47 }
48
49 const char *sbuf_buf(struct sbuf *buf)
50 {
51 return buf->buf;
52 }
53
54 void sbuf_free(struct sbuf *buf)
55 {
56 if (!buf->fixed)
57 XFREE(MTYPE_TMP, buf->buf);
58 }
59
60 void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
61 {
62 va_list args;
63 int written;
64
65 if (!buf->fixed) {
66 int written1, written2;
67 size_t new_size;
68
69 written1 = indent;
70 va_start(args, format);
71 written2 = vsnprintf(NULL, 0, format, args);
72 va_end(args);
73
74 new_size = buf->size;
75 if (written1 >= 0 && written2 >= 0) {
76 while (buf->pos + written1 + written2 >= new_size)
77 new_size *= 2;
78 if (new_size > buf->size) {
79 buf->buf =
80 XREALLOC(MTYPE_TMP, buf->buf, new_size);
81 buf->size = new_size;
82 }
83 }
84 }
85
86 written = snprintf(buf->buf + buf->pos, buf->size - buf->pos, "%*s",
87 indent, "");
88
89 if (written >= 0)
90 buf->pos += written;
91 if (buf->pos > buf->size)
92 buf->pos = buf->size;
93
94 va_start(args, format);
95 written = vsnprintf(buf->buf + buf->pos, buf->size - buf->pos, format,
96 args);
97 va_end(args);
98
99 if (written >= 0)
100 buf->pos += written;
101 if (buf->pos > buf->size)
102 buf->pos = buf->size;
103
104 if (buf->pos == buf->size)
105 assert(!"Buffer filled up!");
106 }