2 dbuf_string.c - Append formatted string to the dynamic buffer
3 version 1.2.0, February 10th, 2008
5 Copyright (c) 2002-2008 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.
33 * The buffer is null terminated.
37 dbuf_append_str (struct dbuf_s *dbuf, const char *str)
43 if (dbuf_append (dbuf, str, len + 1))
54 * Append single character to the end of the buffer.
55 * The buffer is null terminated.
59 dbuf_append_char (struct dbuf_s *dbuf, char chr)
64 if (dbuf_append (dbuf, buf, 2))
74 * Calculate length of the resulting formatted string.
76 * Borrowed from vasprintf.c
80 calc_result_length (const char *format, va_list args)
82 const char *p = format;
83 /* Add one to make sure that it is never zero, which might cause malloc
85 int total_width = strlen (format) + 1;
91 memcpy (&ap, &args, sizeof (va_list));
98 while (strchr ("-+ #0", *p))
103 total_width += abs (va_arg (ap, int));
106 total_width += strtoul (p, (char **) &p, 10);
113 total_width += abs (va_arg (ap, int));
116 total_width += strtoul (p, (char **) &p, 10);
118 while (strchr ("hlL", *p))
120 /* Should be big enough for any format specifier except %s and floats. */
131 (void) va_arg (ap, int);
138 (void) va_arg (ap, double);
139 /* Since an ieee double can have an exponent of 307, we'll
140 make the buffer wide enough to cover the gross case. */
144 total_width += strlen (va_arg (ap, char *));
148 (void) va_arg (ap, char *);
162 * Append the formatted string to the end of the buffer.
163 * The buffer is null terminated.
167 dbuf_vprintf (struct dbuf_s *dbuf, const char *format, va_list args)
169 int size = calc_result_length (format, args);
171 assert (dbuf != NULL);
172 assert (dbuf->alloc != 0);
173 assert (dbuf->buf != NULL);
175 if (0 != _dbuf_expand (dbuf, size))
177 int len = vsprintf (&(((char *)dbuf->buf)[dbuf->len]), format, args);
181 /* if written length is greater then the calculated one,
182 we have a buffer overrun! */
183 assert (len <= size);
194 * Append the formatted string to the end of the buffer.
195 * The buffer is null terminated.
199 dbuf_printf (struct dbuf_s *dbuf, const char *format, ...)
204 va_start (arg, format);
205 len = dbuf_vprintf (dbuf, format, arg);
213 * Append line from file to the dynamic buffer
214 * The buffer is null terminated.
218 dbuf_getline (struct dbuf_s *dbuf, FILE *infp)
223 while ((c = getc (infp)) != '\n' && c != EOF)
227 dbuf_append (dbuf, &chr, 1);
230 /* add trailing NL */
235 dbuf_append (dbuf, &chr, 1);
238 /* terminate the line without increasing the length */
239 if (0 != _dbuf_expand (dbuf, 1))
240 ((char *)dbuf->buf)[dbuf->len] = '\0';
242 return dbuf_get_length (dbuf);
247 * Remove trailing newline from the string.
248 * The buffer is null terminated.
249 * It returns the total number of characters removed.
253 dbuf_chomp (struct dbuf_s *dbuf)
255 size_t i = dbuf->len;
258 if ('\n' == ((char *)dbuf->buf)[i - 1])
261 if ('\r' == ((char *)dbuf->buf)[i - 1])
270 /* terminate the line without increasing the length */
271 if (_dbuf_expand(dbuf, 1) != 0)
272 ((char *)dbuf->buf)[dbuf->len] = '\0';
279 * Write dynamic buffer to the file.
283 dbuf_write (struct dbuf_s *dbuf, FILE *dest)
286 size_t len = dbuf_get_length (dbuf);
287 res = fwrite (dbuf_get_buf (dbuf), 1, len, dest);
293 * Write dynamic buffer to the file and destroy it.
297 dbuf_write_and_destroy (struct dbuf_s *dbuf, FILE *dest)
299 dbuf_write (dbuf, dest);