Skip to content

Commit

Permalink
Rewrite convert_to_{git,working_tree} to use strbuf's.
Browse files Browse the repository at this point in the history
* Now, those functions take an "out" strbuf argument, where they store their
  result if any. In that case, it also returns 1, else it returns 0.
* those functions support "in place" editing, in the sense that it's OK to
  call them this way:
    convert_to_git(path, sb->buf, sb->len, sb);
  When doable, conversions are done in place for real, else the strbuf
  content is just replaced with the new one, transparentely for the caller.

If you want to create a new filter working this way, being the accumulation
of filter1, filter2, ... filtern, then your meta_filter would be:

    int meta_filter(..., const char *src, size_t len, struct strbuf *sb)
    {
        int ret = 0;
        ret |= filter1(...., src, len, sb);
        if (ret) {
            src = sb->buf;
            len = sb->len;
        }
        ret |= filter2(...., src, len, sb);
        if (ret) {
            src = sb->buf;
            len = sb->len;
        }
        ....
        return ret | filtern(..., src, len, sb);
    }

That's why subfilters the convert_to_* functions called were also rewritten
to work this way.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Pierre Habouzit authored and Junio C Hamano committed Sep 17, 2007
1 parent 917c9a7 commit 5ecd293
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 317 deletions.
27 changes: 13 additions & 14 deletions builtin-apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -1446,8 +1446,7 @@ static int read_old_data(struct stat *st, const char *path, char **buf_p, unsign
{
int fd;
unsigned long got;
unsigned long nsize;
char *nbuf;
struct strbuf nbuf;
unsigned long size = *size_p;
char *buf = *buf_p;

Expand All @@ -1466,13 +1465,12 @@ static int read_old_data(struct stat *st, const char *path, char **buf_p, unsign
got += ret;
}
close(fd);
nsize = got;
nbuf = convert_to_git(path, buf, &nsize);
if (nbuf) {
strbuf_init(&nbuf, 0);
if (convert_to_git(path, buf, size, &nbuf)) {
free(buf);
*buf_p = nbuf;
*alloc_p = nsize;
*size_p = nsize;
*buf_p = nbuf.buf;
*alloc_p = nbuf.alloc;
*size_p = nbuf.len;
}
return got != size;
default:
Expand Down Expand Up @@ -2439,7 +2437,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
{
int fd;
char *nbuf;
struct strbuf nbuf;

if (S_ISGITLINK(mode)) {
struct stat st;
Expand All @@ -2458,9 +2456,11 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
if (fd < 0)
return -1;

nbuf = convert_to_working_tree(path, buf, &size);
if (nbuf)
buf = nbuf;
strbuf_init(&nbuf, 0);
if (convert_to_working_tree(path, buf, size, &nbuf)) {
size = nbuf.len;
buf = nbuf.buf;
}

while (size) {
int written = xwrite(fd, buf, size);
Expand All @@ -2473,8 +2473,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
}
if (close(fd) < 0)
die("closing file %s: %s", path, strerror(errno));
if (nbuf)
free(nbuf);
strbuf_release(&nbuf);
return 0;
}

Expand Down
78 changes: 36 additions & 42 deletions builtin-archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,21 @@ static int run_remote_archiver(const char *remote, int argc,
return !!rv;
}

static void *format_subst(const struct commit *commit, const char *format,
unsigned long *sizep)
static void format_subst(const struct commit *commit,
const char *src, size_t len,
struct strbuf *buf)
{
unsigned long len = *sizep;
const char *a = format;
struct strbuf result;
char *to_free = NULL;
struct strbuf fmt;

strbuf_init(&result, 0);
if (src == buf->buf)
to_free = strbuf_detach(buf);
strbuf_init(&fmt, 0);

for (;;) {
const char *b, *c;

b = memmem(a, len, "$Format:", 8);
if (!b || a + len < b + 9)
b = memmem(src, len, "$Format:", 8);
if (!b || src + len < b + 9)
break;
c = memchr(b + 8, '$', len - 8);
if (!c)
Expand All @@ -105,62 +104,57 @@ static void *format_subst(const struct commit *commit, const char *format,
strbuf_reset(&fmt);
strbuf_add(&fmt, b + 8, c - b - 8);

strbuf_add(&result, a, b - a);
format_commit_message(commit, fmt.buf, &result);
len -= c + 1 - a;
a = c + 1;
strbuf_add(buf, src, b - src);
format_commit_message(commit, fmt.buf, buf);
len -= c + 1 - src;
src = c + 1;
}

strbuf_add(&result, a, len);

*sizep = result.len;

strbuf_add(buf, src, len);
strbuf_release(&fmt);
return strbuf_detach(&result);
free(to_free);
}

static void *convert_to_archive(const char *path,
const void *src, unsigned long *sizep,
const struct commit *commit)
static int convert_to_archive(const char *path,
const void *src, size_t len,
struct strbuf *buf,
const struct commit *commit)
{
static struct git_attr *attr_export_subst;
struct git_attr_check check[1];

if (!commit)
return NULL;
return 0;

if (!attr_export_subst)
attr_export_subst = git_attr("export-subst", 12);
if (!attr_export_subst)
attr_export_subst = git_attr("export-subst", 12);

check[0].attr = attr_export_subst;
if (git_checkattr(path, ARRAY_SIZE(check), check))
return NULL;
return 0;
if (!ATTR_TRUE(check[0].value))
return NULL;
return 0;

return format_subst(commit, src, sizep);
format_subst(commit, src, len, buf);
return 1;
}

void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
unsigned long *size,
unsigned long *sizep,
const struct commit *commit)
{
void *buffer, *converted;
void *buffer;

buffer = read_sha1_file(sha1, type, size);
buffer = read_sha1_file(sha1, type, sizep);
if (buffer && S_ISREG(mode)) {
converted = convert_to_working_tree(path, buffer, size);
if (converted) {
free(buffer);
buffer = converted;
}

converted = convert_to_archive(path, buffer, size, commit);
if (converted) {
free(buffer);
buffer = converted;
}
struct strbuf buf;

strbuf_init(&buf, 0);
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
convert_to_working_tree(path, buf.buf, buf.len, &buf);
convert_to_archive(path, buf.buf, buf.len, &buf, commit);
*sizep = buf.len;
buffer = buf.buf;
}

return buffer;
Expand Down
6 changes: 4 additions & 2 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define CACHE_H

#include "git-compat-util.h"
#include "strbuf.h"

#include SHA1_HEADER
#include <zlib.h>
Expand Down Expand Up @@ -589,8 +590,9 @@ extern void trace_printf(const char *format, ...);
extern void trace_argv_printf(const char **argv, int count, const char *format, ...);

/* convert.c */
extern char *convert_to_git(const char *path, const char *src, unsigned long *sizep);
extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep);
/* returns 1 if *dst was used */
extern int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst);
extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);

/* diff.c */
extern int diff_auto_refresh_index;
Expand Down
Loading

0 comments on commit 5ecd293

Please sign in to comment.