X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=builtin-archive.c;h=6f29c2f40a01b3c60eaa9ecfa1ca4d63fe90c8eb;hb=e2b7eaf0ca3897940961d23392d4ff718867ea9f;hp=a90c65ce54a1c3e415b46465a2b4c7bfdffca9ff;hpb=0341091a9ec47576a2fdfab181145fa94c04b810;p=git.git diff --git a/builtin-archive.c b/builtin-archive.c index a90c65ce5..6f29c2f40 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -81,95 +81,81 @@ 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, result_len = 0; - const char *a = format; - char *result = NULL; + char *to_free = NULL; + struct strbuf fmt; + if (src == buf->buf) + to_free = strbuf_detach(buf, NULL); + strbuf_init(&fmt, 0); for (;;) { const char *b, *c; - char *fmt, *formatted = NULL; - unsigned long a_len, fmt_len, formatted_len, allocated = 0; - 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) break; - a_len = b - a; - fmt_len = c - b - 8; - fmt = xmalloc(fmt_len + 1); - memcpy(fmt, b + 8, fmt_len); - fmt[fmt_len] = '\0'; - - formatted_len = format_commit_message(commit, fmt, &formatted, - &allocated); - free(fmt); - result = xrealloc(result, result_len + a_len + formatted_len); - memcpy(result + result_len, a, a_len); - memcpy(result + result_len + a_len, formatted, formatted_len); - result_len += a_len + formatted_len; - len -= c + 1 - a; - a = c + 1; - } + strbuf_reset(&fmt); + strbuf_add(&fmt, b + 8, c - b - 8); - if (result && len) { - result = xrealloc(result, result_len + len); - memcpy(result + result_len, a, len); - result_len += len; + strbuf_add(buf, src, b - src); + format_commit_message(commit, fmt.buf, buf); + len -= c + 1 - src; + src = c + 1; } - - *sizep = result_len; - - return result; + strbuf_add(buf, src, len); + strbuf_release(&fmt); + 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; + size_t size = 0; + + 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); + buffer = strbuf_detach(&buf, &size); + *sizep = size; } return buffer;