Heh. Just for fun, here's an uglier version:
struct wcb_data {
int had_buffer;
int using_buffer;
};
#define WITH_COMMIT_BUFFER_DATA_INIT { 0, 0 } extern void acquire_commit_buffer(struct commit *, struct wcb_data *);
extern void done_with_commit_buffer(struct commit *, struct wcb_data *);
/*
* usage:
* struct wcb_data buf = WITH_COMMIT_BUFFER_INIT;
*
* with_commit_buffer(commit, buf) {
* ...
* }
*/
#define with_commit_buffer(commit, i) \
for (acquire_commit_buffer(commit, &i); \
i.using_buffer; \
done_with_commit_buffer(commit, &i)) void acquire_commit_buffer(struct commit *commit, struct wcb_data *i)
{
enum object_type type;
unsigned long size; assert(!i->using_buffer);
i->using_buffer = 1;
i->had_buffer = !!commit->buffer;
if (i->had_buffer)
return;
commit->buffer = read_sha1_file(commit->object.sha1, &type, &size);
if (!commit->buffer)
die("unable to read commit %s", sha1_to_hex(commit->object.sha1));
} void done_with_commit_buffer(struct commit *commit, struct wcb_data *i)
{
assert(i->using_buffer);
i->using_buffer = 0; if (!i->had_buffer) {
free(commit->buffer);
commit->buffer = NULL;
}
}