summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9cfcca3)
raw | patch | inline | side by side (parent: 9cfcca3)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 4 Sep 2013 20:41:03 +0000 (22:41 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 4 Sep 2013 20:41:03 +0000 (22:41 +0200) |
src/utils/strbuf.c | patch | blob | history |
diff --git a/src/utils/strbuf.c b/src/utils/strbuf.c
index bc24fef5e54c19781c5cd4bef7c3a1036e897945..c8e7e633a27452ade2e8bdb85f078cb542e9e63f 100644 (file)
--- a/src/utils/strbuf.c
+++ b/src/utils/strbuf.c
*/
static int
-strbuf_resize(sdb_strbuf_t *strbuf)
+strbuf_resize(sdb_strbuf_t *strbuf, size_t new_size)
{
char *tmp;
- assert(strbuf->size);
+ if (new_size <= strbuf->size)
+ return 0;
- tmp = realloc(strbuf->string, 2 * strbuf->size);
+ tmp = realloc(strbuf->string, new_size);
if (! tmp)
return -1;
strbuf->string = tmp;
- strbuf->size *= 2;
+ strbuf->size = new_size;
return 0;
} /* strbuf_resize */
{
sdb_strbuf_t *strbuf;
- if (! size)
- return NULL;
-
strbuf = calloc(1, sizeof(*strbuf));
if (! strbuf)
return NULL;
- strbuf->string = malloc(size);
- if (! strbuf->string) {
- free(strbuf);
- return NULL;
+ strbuf->string = NULL;
+ if (size) {
+ strbuf->string = malloc(size);
+ if (! strbuf->string) {
+ free(strbuf);
+ return NULL;
+ }
+
+ strbuf->string[0] = '\0';
}
- strbuf->string[0] = '\0';
strbuf->size = size;
strbuf->pos = 0;
if (! strbuf)
return;
- free(strbuf->string);
+ if (strbuf->string)
+ free(strbuf->string);
free(strbuf);
} /* sdb_strbuf_destroy */
if ((! strbuf) || (! fmt))
return -1;
- assert(strbuf->string[strbuf->pos] == '\0');
+ assert((strbuf->size == 0) || (strbuf->string[strbuf->pos] == '\0'));
if (strbuf->pos >= strbuf->size)
- if (strbuf_resize(strbuf))
+ /* use some arbitrary but somewhat reasonable default */
+ if (strbuf_resize(strbuf, strbuf->size ? 2 * strbuf->size : 64))
return -1;
+ assert(strbuf->size && strbuf->string);
+ assert(strbuf->pos < strbuf->size);
+
/* 'ap' is invalid after calling vsnprintf; thus copy before using it */
va_copy(aq, ap);
status = vsnprintf(strbuf->string + strbuf->pos,
}
if ((size_t)status >= strbuf->size - strbuf->pos) {
- strbuf_resize(strbuf);
+ strbuf_resize(strbuf, (size_t)status + 1);
/* reset string and try again */
strbuf->string[strbuf->pos] = '\0';
if (! strbuf)
return -1;
- strbuf->string[0] = '\0';
- strbuf->pos = 0;
+ if (strbuf->size) {
+ strbuf->string[0] = '\0';
+ strbuf->pos = 0;
+ }
return sdb_strbuf_vappend(strbuf, fmt, ap);
} /* sdb_strbuf_vsprintf */
if (! strbuf)
return -1;
+ assert(strbuf->size || (strbuf->pos < strbuf->size));
+ assert(strbuf->pos <= strbuf->size);
+
while ((strbuf->pos > 0)
&& (strbuf->string[strbuf->pos - 1] == '\n')) {
--strbuf->pos;
{
if (! strbuf)
return NULL;
+ if (! strbuf->size)
+ return "";
return strbuf->string;
} /* sdb_strbuf_string */