From af6eb82262e35687aa8f00d688e327cb845973fa Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 6 Sep 2007 13:20:09 +0200 Subject: Use strbuf API in apply, blame, commit-tree and diff Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- diff.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 0d30d05263..c054b234b8 100644 --- a/diff.c +++ b/diff.c @@ -9,6 +9,7 @@ #include "xdiff-interface.h" #include "color.h" #include "attr.h" +#include "strbuf.h" #ifdef NO_FAST_WORKING_DIRECTORY #define FAST_WORKING_DIRECTORY 0 @@ -1545,26 +1546,16 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int static int populate_from_stdin(struct diff_filespec *s) { -#define INCREMENT 1024 - char *buf; - unsigned long size; - ssize_t got; - - size = 0; - buf = NULL; - while (1) { - buf = xrealloc(buf, size + INCREMENT); - got = xread(0, buf + size, INCREMENT); - if (!got) - break; /* EOF */ - if (got < 0) - return error("error while reading from stdin %s", + struct strbuf buf; + + strbuf_init(&buf); + if (strbuf_read(&buf, 0) < 0) + return error("error while reading from stdin %s", strerror(errno)); - size += got; - } + s->should_munmap = 0; - s->data = buf; - s->size = size; + s->size = buf.len; + s->data = strbuf_detach(&buf); s->should_free = 1; return 0; } -- cgit v1.2.3 From f1696ee398e92bcea3cdc7b3da85d8e0f77f6c50 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Mon, 10 Sep 2007 12:35:04 +0200 Subject: Strbuf API extensions and fixes. * Add strbuf_rtrim to remove trailing spaces. * Add strbuf_insert to insert data at a given position. * Off-by one fix in strbuf_addf: strbuf_avail() does not counts the final \0 so the overflow test for snprintf is the strict comparison. This is not critical as the growth mechanism chosen will always allocate _more_ memory than asked, so the second test will not fail. It's some kind of miracle though. * Add size extension hints for strbuf_init and strbuf_read. If 0, default applies, else: + initial buffer has the given size for strbuf_init. + first growth checks it has at least this size rather than the default 8192. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- diff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 26d7bb96bc..7290309ea9 100644 --- a/diff.c +++ b/diff.c @@ -1548,8 +1548,8 @@ static int populate_from_stdin(struct diff_filespec *s) { struct strbuf buf; - strbuf_init(&buf); - if (strbuf_read(&buf, 0) < 0) + strbuf_init(&buf, 0); + if (strbuf_read(&buf, 0, 0) < 0) return error("error while reading from stdin %s", strerror(errno)); -- cgit v1.2.3 From 5ecd293d1420bf641a927a015877950f4d79c067 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 16 Sep 2007 15:51:04 +0200 Subject: Rewrite convert_to_{git,working_tree} to use strbuf's. * 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 Acked-by: Linus Torvalds Signed-off-by: Junio C Hamano --- diff.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 7290309ea9..f41bcd94ab 100644 --- a/diff.c +++ b/diff.c @@ -1600,10 +1600,9 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) if (!s->sha1_valid || reuse_worktree_file(s->path, s->sha1, 0)) { + struct strbuf buf; struct stat st; int fd; - char *buf; - unsigned long size; if (!strcmp(s->path, "-")) return populate_from_stdin(s); @@ -1644,13 +1643,12 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) /* * Convert from working tree format to canonical git format */ - size = s->size; - buf = convert_to_git(s->path, s->data, &size); - if (buf) { + strbuf_init(&buf, 0); + if (convert_to_git(s->path, s->data, s->size, &buf)) { munmap(s->data, s->size); s->should_munmap = 0; - s->data = buf; - s->size = size; + s->data = buf.buf; + s->size = buf.len; s->should_free = 1; } } -- cgit v1.2.3 From ba3ed09728cb25e004d3b732de14fca8aeb602f6 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 15 Sep 2007 15:56:50 +0200 Subject: Now that cache.h needs strbuf.h, remove useless includes. Signed-off-by: Pierre Habouzit Acked-by: Linus Torvalds Signed-off-by: Junio C Hamano --- diff.c | 1 - 1 file changed, 1 deletion(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index f41bcd94ab..56b672c4f0 100644 --- a/diff.c +++ b/diff.c @@ -9,7 +9,6 @@ #include "xdiff-interface.h" #include "color.h" #include "attr.h" -#include "strbuf.h" #ifdef NO_FAST_WORKING_DIRECTORY #define FAST_WORKING_DIRECTORY 0 -- cgit v1.2.3 From 182af8343c307436bb5364309aa6d4d46fa5911d Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 16 Sep 2007 00:32:36 +0200 Subject: Use xmemdupz() in many places. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- diff.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index a5b69ed2d2..2216d756d1 100644 --- a/diff.c +++ b/diff.c @@ -83,13 +83,8 @@ static int parse_lldiff_command(const char *var, const char *ep, const char *val if (!strncmp(drv->name, name, namelen) && !drv->name[namelen]) break; if (!drv) { - char *namebuf; drv = xcalloc(1, sizeof(struct ll_diff_driver)); - namebuf = xmalloc(namelen + 1); - memcpy(namebuf, name, namelen); - namebuf[namelen] = 0; - drv->name = namebuf; - drv->next = NULL; + drv->name = xmemdupz(name, namelen); if (!user_diff_tail) user_diff_tail = &user_diff; *user_diff_tail = drv; @@ -126,12 +121,8 @@ static int parse_funcname_pattern(const char *var, const char *ep, const char *v if (!strncmp(pp->name, name, namelen) && !pp->name[namelen]) break; if (!pp) { - char *namebuf; pp = xcalloc(1, sizeof(*pp)); - namebuf = xmalloc(namelen + 1); - memcpy(namebuf, name, namelen); - namebuf[namelen] = 0; - pp->name = namebuf; + pp->name = xmemdupz(name, namelen); pp->next = funcname_pattern_list; funcname_pattern_list = pp; } -- cgit v1.2.3 From 663af3422a648e87945e4d8c0cc3e13671f2bbde Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 20 Sep 2007 00:42:15 +0200 Subject: Full rework of quote_c_style and write_name_quoted. * quote_c_style works on a strbuf instead of a wild buffer. * quote_c_style is now clever enough to not add double quotes if not needed. * write_name_quoted inherits those advantages, but also take a different set of arguments. Now instead of asking for quotes or not, you pass a "terminator". If it's \0 then we assume you don't want to escape, else C escaping is performed. In any case, the terminator is also appended to the stream. It also no longer takes the prefix/prefix_len arguments, as it's seldomly used, and makes some optimizations harder. * write_name_quotedpfx is created to work like write_name_quoted and take the prefix/prefix_len arguments. Thanks to those API changes, diff.c has somehow lost weight, thanks to the removal of functions that were wrappers around the old write_name_quoted trying to give it a semantics like the new one, but performing a lot of allocations for this goal. Now we always write directly to the stream, no intermediate allocation is performed. As a side effect of the refactor in builtin-apply.c, the length of the bar graphs in diffstats are not affected anymore by the fact that the path was clipped. Signed-off-by: Pierre Habouzit --- diff.c | 303 ++++++++++++++++++++++++----------------------------------------- 1 file changed, 110 insertions(+), 193 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 2216d756d1..fb6d077f06 100644 --- a/diff.c +++ b/diff.c @@ -181,44 +181,23 @@ int git_diff_ui_config(const char *var, const char *value) return git_default_config(var, value); } -static char *quote_one(const char *str) -{ - int needlen; - char *xp; - - if (!str) - return NULL; - needlen = quote_c_style(str, NULL, NULL, 0); - if (!needlen) - return xstrdup(str); - xp = xmalloc(needlen + 1); - quote_c_style(str, xp, NULL, 0); - return xp; -} - static char *quote_two(const char *one, const char *two) { int need_one = quote_c_style(one, NULL, NULL, 1); int need_two = quote_c_style(two, NULL, NULL, 1); - char *xp; + struct strbuf res; + strbuf_init(&res, 0); if (need_one + need_two) { - if (!need_one) need_one = strlen(one); - if (!need_two) need_one = strlen(two); - - xp = xmalloc(need_one + need_two + 3); - xp[0] = '"'; - quote_c_style(one, xp + 1, NULL, 1); - quote_c_style(two, xp + need_one + 1, NULL, 1); - strcpy(xp + need_one + need_two + 1, "\""); - return xp; + strbuf_addch(&res, '"'); + quote_c_style(one, &res, NULL, 1); + quote_c_style(two, &res, NULL, 1); + strbuf_addch(&res, '"'); + } else { + strbuf_addstr(&res, one); + strbuf_addstr(&res, two); } - need_one = strlen(one); - need_two = strlen(two); - xp = xmalloc(need_one + need_two + 1); - strcpy(xp, one); - strcpy(xp + need_one, two); - return xp; + return res.buf; } static const char *external_diff(void) @@ -670,27 +649,20 @@ static char *pprint_rename(const char *a, const char *b) { const char *old = a; const char *new = b; - char *name = NULL; + struct strbuf name; int pfx_length, sfx_length; int len_a = strlen(a); int len_b = strlen(b); + int a_midlen, b_midlen; int qlen_a = quote_c_style(a, NULL, NULL, 0); int qlen_b = quote_c_style(b, NULL, NULL, 0); + strbuf_init(&name, 0); if (qlen_a || qlen_b) { - if (qlen_a) len_a = qlen_a; - if (qlen_b) len_b = qlen_b; - name = xmalloc( len_a + len_b + 5 ); - if (qlen_a) - quote_c_style(a, name, NULL, 0); - else - memcpy(name, a, len_a); - memcpy(name + len_a, " => ", 4); - if (qlen_b) - quote_c_style(b, name + len_a + 4, NULL, 0); - else - memcpy(name + len_a + 4, b, len_b + 1); - return name; + quote_c_style(a, &name, NULL, 0); + strbuf_addstr(&name, " => "); + quote_c_style(b, &name, NULL, 0); + return name.buf; } /* Find common prefix */ @@ -719,24 +691,26 @@ static char *pprint_rename(const char *a, const char *b) * pfx{sfx-a => sfx-b} * name-a => name-b */ + a_midlen = len_a - pfx_length - sfx_length; + b_midlen = len_b - pfx_length - sfx_length; + if (a_midlen < 0) + a_midlen = 0; + if (b_midlen < 0) + b_midlen = 0; + + strbuf_grow(&name, pfx_length + a_midlen + b_midlen + sfx_length + 7); if (pfx_length + sfx_length) { - int a_midlen = len_a - pfx_length - sfx_length; - int b_midlen = len_b - pfx_length - sfx_length; - if (a_midlen < 0) a_midlen = 0; - if (b_midlen < 0) b_midlen = 0; - - name = xmalloc(pfx_length + a_midlen + b_midlen + sfx_length + 7); - sprintf(name, "%.*s{%.*s => %.*s}%s", - pfx_length, a, - a_midlen, a + pfx_length, - b_midlen, b + pfx_length, - a + len_a - sfx_length); + strbuf_add(&name, a, pfx_length); + strbuf_addch(&name, '{'); } - else { - name = xmalloc(len_a + len_b + 5); - sprintf(name, "%s => %s", a, b); + strbuf_add(&name, a + pfx_length, a_midlen); + strbuf_addstr(&name, " => "); + strbuf_add(&name, b + pfx_length, b_midlen); + if (pfx_length + sfx_length) { + strbuf_addch(&name, '}'); + strbuf_add(&name, a + len_a - sfx_length, sfx_length); } - return name; + return name.buf; } struct diffstat_t { @@ -849,12 +823,13 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options) int change = file->added + file->deleted; if (!file->is_renamed) { /* renames are already quoted by pprint_rename */ - len = quote_c_style(file->name, NULL, NULL, 0); - if (len) { - char *qname = xmalloc(len + 1); - quote_c_style(file->name, qname, NULL, 0); + struct strbuf buf; + strbuf_init(&buf, 0); + if (quote_c_style(file->name, &buf, NULL, 0)) { free(file->name); - file->name = qname; + file->name = buf.buf; + } else { + strbuf_release(&buf); } } @@ -992,12 +967,12 @@ static void show_numstat(struct diffstat_t* data, struct diff_options *options) printf("-\t-\t"); else printf("%d\t%d\t", file->added, file->deleted); - if (options->line_termination && !file->is_renamed && - quote_c_style(file->name, NULL, NULL, 0)) - quote_c_style(file->name, NULL, stdout, 0); - else + if (!file->is_renamed) { + write_name_quoted(file->name, stdout, options->line_termination); + } else { fputs(file->name, stdout); - putchar(options->line_termination); + putchar(options->line_termination); + } } } @@ -1941,50 +1916,46 @@ static int similarity_index(struct diff_filepair *p) static void run_diff(struct diff_filepair *p, struct diff_options *o) { const char *pgm = external_diff(); - char msg[PATH_MAX*2+300], *xfrm_msg; - struct diff_filespec *one; - struct diff_filespec *two; + struct strbuf msg; + char *xfrm_msg; + struct diff_filespec *one = p->one; + struct diff_filespec *two = p->two; const char *name; const char *other; - char *name_munged, *other_munged; int complete_rewrite = 0; - int len; + if (DIFF_PAIR_UNMERGED(p)) { - /* unmerged */ run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, o, 0); return; } - name = p->one->path; + name = p->one->path; other = (strcmp(name, p->two->path) ? p->two->path : NULL); - name_munged = quote_one(name); - other_munged = quote_one(other); - one = p->one; two = p->two; - diff_fill_sha1_info(one); diff_fill_sha1_info(two); - len = 0; + strbuf_init(&msg, PATH_MAX * 2 + 300); switch (p->status) { case DIFF_STATUS_COPIED: - len += snprintf(msg + len, sizeof(msg) - len, - "similarity index %d%%\n" - "copy from %s\n" - "copy to %s\n", - similarity_index(p), name_munged, other_munged); + strbuf_addf(&msg, "similarity index %d%%", similarity_index(p)); + strbuf_addstr(&msg, "\ncopy from "); + quote_c_style(name, &msg, NULL, 0); + strbuf_addstr(&msg, "\ncopy to "); + quote_c_style(other, &msg, NULL, 0); + strbuf_addch(&msg, '\n'); break; case DIFF_STATUS_RENAMED: - len += snprintf(msg + len, sizeof(msg) - len, - "similarity index %d%%\n" - "rename from %s\n" - "rename to %s\n", - similarity_index(p), name_munged, other_munged); + strbuf_addf(&msg, "similarity index %d%%", similarity_index(p)); + strbuf_addstr(&msg, "\nrename from "); + quote_c_style(name, &msg, NULL, 0); + strbuf_addstr(&msg, "\nrename to "); + quote_c_style(other, &msg, NULL, 0); + strbuf_addch(&msg, '\n'); break; case DIFF_STATUS_MODIFIED: if (p->score) { - len += snprintf(msg + len, sizeof(msg) - len, - "dissimilarity index %d%%\n", + strbuf_addf(&msg, "dissimilarity index %d%%\n", similarity_index(p)); complete_rewrite = 1; break; @@ -2004,19 +1975,17 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) abbrev = 40; } - len += snprintf(msg + len, sizeof(msg) - len, - "index %.*s..%.*s", + strbuf_addf(&msg, "index %.*s..%.*s", abbrev, sha1_to_hex(one->sha1), abbrev, sha1_to_hex(two->sha1)); if (one->mode == two->mode) - len += snprintf(msg + len, sizeof(msg) - len, - " %06o", one->mode); - len += snprintf(msg + len, sizeof(msg) - len, "\n"); + strbuf_addf(&msg, " %06o", one->mode); + strbuf_addch(&msg, '\n'); } - if (len) - msg[--len] = 0; - xfrm_msg = len ? msg : NULL; + if (msg.len) + strbuf_setlen(&msg, msg.len - 1); + xfrm_msg = msg.len ? msg.buf : NULL; if (!pgm && DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) && @@ -2035,8 +2004,7 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) run_diff_cmd(pgm, name, other, one, two, xfrm_msg, o, complete_rewrite); - free(name_munged); - free(other_munged); + strbuf_release(&msg); } static void run_diffstat(struct diff_filepair *p, struct diff_options *o, @@ -2492,72 +2460,30 @@ const char *diff_unique_abbrev(const unsigned char *sha1, int len) return sha1_to_hex(sha1); } -static void diff_flush_raw(struct diff_filepair *p, - struct diff_options *options) +static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt) { - int two_paths; - char status[10]; - int abbrev = options->abbrev; - const char *path_one, *path_two; - int inter_name_termination = '\t'; - int line_termination = options->line_termination; - - if (!line_termination) - inter_name_termination = 0; + int line_termination = opt->line_termination; + int inter_name_termination = line_termination ? '\t' : '\0'; - path_one = p->one->path; - path_two = p->two->path; - if (line_termination) { - path_one = quote_one(path_one); - path_two = quote_one(path_two); + if (!(opt->output_format & DIFF_FORMAT_NAME_STATUS)) { + printf(":%06o %06o %s ", p->one->mode, p->two->mode, + diff_unique_abbrev(p->one->sha1, opt->abbrev)); + printf("%s ", diff_unique_abbrev(p->two->sha1, opt->abbrev)); } - - if (p->score) - sprintf(status, "%c%03d", p->status, similarity_index(p)); - else { - status[0] = p->status; - status[1] = 0; - } - switch (p->status) { - case DIFF_STATUS_COPIED: - case DIFF_STATUS_RENAMED: - two_paths = 1; - break; - case DIFF_STATUS_ADDED: - case DIFF_STATUS_DELETED: - two_paths = 0; - break; - default: - two_paths = 0; - break; - } - if (!(options->output_format & DIFF_FORMAT_NAME_STATUS)) { - printf(":%06o %06o %s ", - p->one->mode, p->two->mode, - diff_unique_abbrev(p->one->sha1, abbrev)); - printf("%s ", - diff_unique_abbrev(p->two->sha1, abbrev)); + if (p->score) { + printf("%c%03d%c", p->status, similarity_index(p), + inter_name_termination); + } else { + printf("%c%c", p->status, inter_name_termination); } - printf("%s%c%s", status, inter_name_termination, - two_paths || p->one->mode ? path_one : path_two); - if (two_paths) - printf("%c%s", inter_name_termination, path_two); - putchar(line_termination); - if (path_one != p->one->path) - free((void*)path_one); - if (path_two != p->two->path) - free((void*)path_two); -} -static void diff_flush_name(struct diff_filepair *p, struct diff_options *opt) -{ - char *path = p->two->path; - - if (opt->line_termination) - path = quote_one(p->two->path); - printf("%s%c", path, opt->line_termination); - if (p->two->path != path) - free(path); + if (p->status == DIFF_STATUS_COPIED || p->status == DIFF_STATUS_RENAMED) { + write_name_quoted(p->one->path, stdout, inter_name_termination); + write_name_quoted(p->two->path, stdout, line_termination); + } else { + const char *path = p->one->mode ? p->one->path : p->two->path; + write_name_quoted(path, stdout, line_termination); + } } int diff_unmodified_pair(struct diff_filepair *p) @@ -2567,14 +2493,11 @@ int diff_unmodified_pair(struct diff_filepair *p) * let transformers to produce diff_filepairs any way they want, * and filter and clean them up here before producing the output. */ - struct diff_filespec *one, *two; + struct diff_filespec *one = p->one, *two = p->two; if (DIFF_PAIR_UNMERGED(p)) return 0; /* unmerged is interesting */ - one = p->one; - two = p->two; - /* deletion, addition, mode or type change * and rename are all interesting. */ @@ -2763,32 +2686,27 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt) else if (fmt & (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME_STATUS)) diff_flush_raw(p, opt); else if (fmt & DIFF_FORMAT_NAME) - diff_flush_name(p, opt); + write_name_quoted(p->two->path, stdout, opt->line_termination); } static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs) { - char *name = quote_one(fs->path); if (fs->mode) - printf(" %s mode %06o %s\n", newdelete, fs->mode, name); + printf(" %s mode %06o ", newdelete, fs->mode); else - printf(" %s %s\n", newdelete, name); - free(name); + printf(" %s ", newdelete); + write_name_quoted(fs->path, stdout, '\n'); } static void show_mode_change(struct diff_filepair *p, int show_name) { if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) { + printf(" mode change %06o => %06o%c", p->one->mode, p->two->mode, + show_name ? ' ' : '\n'); if (show_name) { - char *name = quote_one(p->two->path); - printf(" mode change %06o => %06o %s\n", - p->one->mode, p->two->mode, name); - free(name); + write_name_quoted(p->two->path, stdout, '\n'); } - else - printf(" mode change %06o => %06o\n", - p->one->mode, p->two->mode); } } @@ -2818,12 +2736,11 @@ static void diff_summary(struct diff_filepair *p) break; default: if (p->score) { - char *name = quote_one(p->two->path); - printf(" rewrite %s (%d%%)\n", name, - similarity_index(p)); - free(name); - show_mode_change(p, 0); - } else show_mode_change(p, 1); + puts(" rewrite "); + write_name_quoted(p->two->path, stdout, ' '); + printf("(%d%%)\n", similarity_index(p)); + } + show_mode_change(p, !p->score); break; } } @@ -2837,14 +2754,14 @@ struct patch_id_t { static int remove_space(char *line, int len) { int i; - char *dst = line; - unsigned char c; + char *dst = line; + unsigned char c; - for (i = 0; i < len; i++) - if (!isspace((c = line[i]))) - *dst++ = c; + for (i = 0; i < len; i++) + if (!isspace((c = line[i]))) + *dst++ = c; - return dst - line; + return dst - line; } static void patch_id_consume(void *priv, char *line, unsigned long len) -- cgit v1.2.3 From b315c5c08139c0d3c1e4867a305334e29da01d07 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 27 Sep 2007 12:58:23 +0200 Subject: 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 Signed-off-by: Junio C Hamano --- diff.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index fb6d077f06..ab575191d1 100644 --- a/diff.c +++ b/diff.c @@ -197,7 +197,7 @@ static char *quote_two(const char *one, const char *two) strbuf_addstr(&res, one); strbuf_addstr(&res, two); } - return res.buf; + return strbuf_detach(&res, NULL); } static const char *external_diff(void) @@ -662,7 +662,7 @@ static char *pprint_rename(const char *a, const char *b) quote_c_style(a, &name, NULL, 0); strbuf_addstr(&name, " => "); quote_c_style(b, &name, NULL, 0); - return name.buf; + return strbuf_detach(&name, NULL); } /* Find common prefix */ @@ -710,7 +710,7 @@ static char *pprint_rename(const char *a, const char *b) strbuf_addch(&name, '}'); strbuf_add(&name, a + len_a - sfx_length, sfx_length); } - return name.buf; + return strbuf_detach(&name, NULL); } struct diffstat_t { @@ -827,7 +827,7 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options) strbuf_init(&buf, 0); if (quote_c_style(file->name, &buf, NULL, 0)) { free(file->name); - file->name = buf.buf; + file->name = strbuf_detach(&buf, NULL); } else { strbuf_release(&buf); } @@ -1519,8 +1519,7 @@ static int populate_from_stdin(struct diff_filespec *s) strerror(errno)); s->should_munmap = 0; - s->size = buf.len; - s->data = strbuf_detach(&buf); + s->data = strbuf_detach(&buf, &s->size); s->should_free = 1; return 0; } @@ -1612,8 +1611,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) if (convert_to_git(s->path, s->data, s->size, &buf)) { munmap(s->data, s->size); s->should_munmap = 0; - s->data = buf.buf; - s->size = buf.len; + s->data = strbuf_detach(&buf, &s->size); s->should_free = 1; } } -- cgit v1.2.3