4 * Implementation of the dynamic string abstract data type.
6 * Copyright (c) 2006 Juergen Schoenwaelder, International University Bremen.
8 * See the file "COPYING" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 * @(#) $Id: smilint.c 1867 2004-10-06 13:45:31Z strauss $
27 # if defined __va_copy
28 # define va_copy __va_copy /* C99 draft proposal */
30 # define va_copy(lhs,rhs) (lhs) = (rhs)
35 /* These functions should not be needed if inlining works properly. */
37 dstring_str(dstring_t *ds)
39 return ds ? ds->str : NULL;
43 dstring_len(dstring_t *ds)
45 return ds ? ds->len : 0;
49 static inline dstring_t*
50 dstring_grow(dstring_t *ds, size_t len)
53 ds->str = realloc(ds->str, len + 1);
68 ds = calloc(1, sizeof(dstring_t));
72 return dstring_grow(ds, 0);
76 dstring_delete(dstring_t *ds)
79 if (ds->str) free(ds->str);
86 dstring_assign(dstring_t *ds, const char *s)
89 ds = dstring_grow(ds, strlen(s));
96 dstring_append(dstring_t *ds, const char *s)
99 ds = dstring_grow(ds, ds->len + strlen(s));
107 dstring_append_char(dstring_t *ds, const char c)
110 ds = dstring_grow(ds, ds->len + 1);
111 ds->str[ds->len-1] = c;
118 dstring_concat(dstring_t *ds, ...)
125 for (s = va_arg(ap, char*); s; s = va_arg(ap, char*)) {
126 ds = dstring_append(ds, s);
134 dstring_append_printf(dstring_t *ds, const char *format, ...)
138 va_start(ap, format);
139 ds = dstring_append_vprintf(ds, format, ap);
145 dstring_append_vprintf(dstring_t *ds, const char *format, va_list _ap)
154 n = vsnprintf(ds->str + o, ds->len+1 - o, format, ap);
156 if (n > -1 && n+o <= ds->len) {
158 dstring_truncate(ds, n+o);
163 ds = dstring_grow(ds, n + o); /* C99 */
165 ds = dstring_grow(ds, ds->len + ds->len); /* GLIBC */
174 dstring_printf(dstring_t *ds, const char *format, ...)
178 va_start(ap, format);
179 ds = dstring_vprintf(ds, format, ap);
185 dstring_vprintf(dstring_t *ds, const char *format, va_list _ap)
193 n = vsnprintf(ds->str, ds->len+1, format, ap);
195 if (n > -1 && n <= ds->len) {
197 dstring_truncate(ds, n);
202 ds = dstring_grow(ds, n); /* C99 */
204 ds = dstring_grow(ds, ds->len + ds->len); /* GLIBC */
212 dstring_truncate(dstring_t *ds, int len)
214 if (ds && len < ds->len) {
215 ds = dstring_grow(ds, len);
221 dstring_expand(dstring_t *ds, int len, char fill)
223 if (ds && len > ds->len) {
224 int i, old = ds->len;
225 ds = dstring_grow(ds, len);
226 for (i = old; i < len; i++) {