strbuf change: be sure ->buf is never ever NULL.

For that purpose, the ->buf is always initialized with a char * buf living
in the strbuf module. It is made a char * so that we can sloppily accept
things that perform: sb->buf[0] = '\0', and because you can't pass "" as an
initializer for ->buf without making gcc unhappy for very good reasons.

strbuf_init/_detach/_grow have been fixed to trust ->alloc and not ->buf
anymore.

as a consequence strbuf_detach is _mandatory_ to detach a buffer, copying
->buf isn't an option anymore, if ->buf is going to escape from the scope,
and eventually be free'd.

API changes:
  * strbuf_setlen now always works, so just make strbuf_reset a convenience
    macro.
  * strbuf_detatch takes a size_t* optional argument (meaning it can be
    NULL) to copy the buffer's len, as it was needed for this refactor to
    make the code more readable, and working like the callers.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Pierre Habouzit
2007-09-27 12:58:23 +02:00
committed by Junio C Hamano
parent 690b61f5f1
commit b315c5c081
13 changed files with 48 additions and 47 deletions

View File

@ -1,27 +1,33 @@
#include "cache.h"
/*
* Used as the default ->buf value, so that people can always assume
* buf is non NULL and ->buf is NUL terminated even for a freshly
* initialized strbuf.
*/
char strbuf_slopbuf[1];
void strbuf_init(struct strbuf *sb, size_t hint)
{
memset(sb, 0, sizeof(*sb));
sb->alloc = sb->len = 0;
sb->buf = strbuf_slopbuf;
if (hint)
strbuf_grow(sb, hint);
}
void strbuf_release(struct strbuf *sb)
{
free(sb->buf);
memset(sb, 0, sizeof(*sb));
if (sb->alloc) {
free(sb->buf);
strbuf_init(sb, 0);
}
}
void strbuf_reset(struct strbuf *sb)
char *strbuf_detach(struct strbuf *sb, size_t *sz)
{
if (sb->len)
strbuf_setlen(sb, 0);
}
char *strbuf_detach(struct strbuf *sb)
{
char *res = sb->buf;
char *res = sb->alloc ? sb->buf : NULL;
if (sz)
*sz = sb->len;
strbuf_init(sb, 0);
return res;
}
@ -40,6 +46,8 @@ void strbuf_grow(struct strbuf *sb, size_t extra)
{
if (sb->len + extra + 1 <= sb->len)
die("you want to use way too much memory");
if (!sb->alloc)
sb->buf = NULL;
ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
}