2 dbuf_string.c - Append formatted string to the dynamic buffer
3 version 1.1.0, December 29th, 2007
5 Copyright (c) 2002-2007 Borut Razem
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA.
28 #include "dbuf_string.h"
32 * Append string to the end of the buffer.
36 dbuf_append_str (struct dbuf_s *dbuf, const char *str)
40 return dbuf_append (dbuf, str, strlen(str));
45 * Append single character to the end of the buffer.
49 dbuf_append_char (struct dbuf_s *dbuf, char chr)
51 return dbuf_append (dbuf, &chr, 1);
55 * Calculate length of the resulting formatted string.
57 * Borrowed from vasprintf.c
61 calc_result_length (const char *format, va_list args)
63 const char *p = format;
64 /* Add one to make sure that it is never zero, which might cause malloc
66 int total_width = strlen (format) + 1;
72 memcpy (&ap, &args, sizeof (va_list));
79 while (strchr ("-+ #0", *p))
84 total_width += abs (va_arg (ap, int));
87 total_width += strtoul (p, (char **) &p, 10);
94 total_width += abs (va_arg (ap, int));
97 total_width += strtoul (p, (char **) &p, 10);
99 while (strchr ("hlL", *p))
101 /* Should be big enough for any format specifier except %s and floats. */
112 (void) va_arg (ap, int);
119 (void) va_arg (ap, double);
120 /* Since an ieee double can have an exponent of 307, we'll
121 make the buffer wide enough to cover the gross case. */
125 total_width += strlen (va_arg (ap, char *));
129 (void) va_arg (ap, char *);
143 * Append the formatted string to the end of the buffer.
147 dbuf_vprintf (struct dbuf_s *dbuf, const char *format, va_list args)
149 int size = calc_result_length (format, args);
151 assert (dbuf != NULL);
152 assert (dbuf->alloc != 0);
153 assert (dbuf->buf != NULL);
155 if (0 != _dbuf_expand (dbuf, size))
157 int len = vsprintf (&(((char *)dbuf->buf)[dbuf->len]), format, args);
161 /* if written length is greater then the calculated one,
162 we have a buffer overrun! */
163 assert (len <= size);
174 * Append the formatted string to the end of the buffer.
178 dbuf_printf (struct dbuf_s *dbuf, const char *format, ...)
183 va_start (arg, format);
184 len = dbuf_vprintf (dbuf, format, arg);
192 * Append line from file to the dynamic buffer
196 dbuf_getline (struct dbuf_s *dbuf, FILE *infp)
201 while ((c = getc (infp)) != '\n' && c != EOF)
205 dbuf_append (dbuf, &chr, 1);
208 /* add trailing NL */
213 dbuf_append (dbuf, &chr, 1);
216 /* terminate the line without increasing the length */
217 if (0 != _dbuf_expand (dbuf, 1))
218 ((char *)dbuf->buf)[dbuf->len] = '\0';
220 return dbuf_get_length (dbuf);
225 * Write dynamic buffer to the file.
229 dbuf_write (struct dbuf_s *dbuf, FILE *dest)
231 fwrite (dbuf_get_buf (dbuf), 1, dbuf_get_length (dbuf), dest);
236 * Write dynamic buffer to the file and destroy it.
240 dbuf_write_and_destroy (struct dbuf_s *dbuf, FILE *dest)
242 dbuf_write (dbuf, dest);