diff options
Diffstat (limited to 'line-log.c')
-rw-r--r-- | line-log.c | 100 |
1 files changed, 54 insertions, 46 deletions
diff --git a/line-log.c b/line-log.c index 24a1ecb677..bc67b75d10 100644 --- a/line-log.c +++ b/line-log.c @@ -1,8 +1,8 @@ #include "git-compat-util.h" +#include "diffcore.h" #include "line-range.h" #include "hex.h" #include "tag.h" -#include "blob.h" #include "tree.h" #include "diff.h" #include "commit.h" @@ -12,8 +12,6 @@ #include "xdiff-interface.h" #include "strbuf.h" #include "log-tree.h" -#include "graph.h" -#include "userdiff.h" #include "line-log.h" #include "setup.h" #include "strvec.h" @@ -250,8 +248,10 @@ static void line_log_data_init(struct line_log_data *r) static void line_log_data_clear(struct line_log_data *r) { range_set_release(&r->ranges); + free(r->path); if (r->pair) diff_free_filepair(r->pair); + diff_ranges_release(&r->diff); } static void free_line_log_data(struct line_log_data *r) @@ -573,7 +573,8 @@ parse_lines(struct repository *r, struct commit *commit, struct line_log_data *p; for_each_string_list_item(item, args) { - const char *name_part, *range_part; + const char *name_part; + char *range_part; char *full_name; struct diff_filespec *spec; long begin = 0, end = 0; @@ -617,6 +618,7 @@ parse_lines(struct repository *r, struct commit *commit, free_filespec(spec); FREE_AND_NULL(ends); + free(range_part); } for (p = ranges; p; p = p->next) @@ -762,15 +764,13 @@ static void parse_pathspec_from_ranges(struct pathspec *pathspec, { struct line_log_data *r; struct strvec array = STRVEC_INIT; - const char **paths; for (r = range; r; r = r->next) strvec_push(&array, r->path); - paths = strvec_detach(&array); - parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", paths); - /* strings are now owned by pathspec */ - free(paths); + parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", array.v); + + strvec_clear(&array); } void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args) @@ -783,21 +783,22 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list add_line_range(rev, commit, range); parse_pathspec_from_ranges(&rev->diffopt.pathspec, range); + + free_line_log_data(range); } static void move_diff_queue(struct diff_queue_struct *dst, struct diff_queue_struct *src) { assert(src != dst); - memcpy(dst, src, sizeof(struct diff_queue_struct)); - DIFF_QUEUE_CLEAR(src); + memcpy(dst, src, sizeof(*dst)); + diff_queue_init(src); } static void filter_diffs_for_paths(struct line_log_data *range, int keep_deletions) { int i; - struct diff_queue_struct outq; - DIFF_QUEUE_CLEAR(&outq); + struct diff_queue_struct outq = DIFF_QUEUE_INIT; for (i = 0; i < diff_queued_diff.nr; i++) { struct diff_filepair *p = diff_queued_diff.queue[i]; @@ -852,12 +853,12 @@ static void queue_diffs(struct line_log_data *range, clear_pathspec(&opt->pathspec); parse_pathspec_from_ranges(&opt->pathspec, range); } - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_clear(&diff_queued_diff); diff_tree_oid(parent_tree_oid, tree_oid, "", opt); if (opt->detect_rename && diff_might_be_rename()) { /* must look at the full tree diff to detect renames */ clear_pathspec(&opt->pathspec); - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_clear(&diff_queued_diff); diff_tree_oid(parent_tree_oid, tree_oid, "", opt); @@ -899,18 +900,6 @@ static void print_line(const char *prefix, char first, fputs("\\ No newline at end of file\n", file); } -static char *output_prefix(struct diff_options *opt) -{ - char *prefix = ""; - - if (opt->output_prefix) { - struct strbuf *sb = opt->output_prefix(opt, opt->output_prefix_data); - prefix = sb->buf; - } - - return prefix; -} - static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *range) { unsigned int i, j = 0; @@ -920,7 +909,7 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang struct diff_ranges *diff = &range->diff; struct diff_options *opt = &rev->diffopt; - char *prefix = output_prefix(opt); + const char *prefix = diff_line_prefix(opt); const char *c_reset = diff_get_color(opt->use_color, DIFF_RESET); const char *c_frag = diff_get_color(opt->use_color, DIFF_FRAGINFO); const char *c_meta = diff_get_color(opt->use_color, DIFF_METAINFO); @@ -929,7 +918,7 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang const char *c_context = diff_get_color(opt->use_color, DIFF_CONTEXT); if (!pair || !diff) - return; + goto out; if (pair->one->oid_valid) fill_line_ends(rev->diffopt.repo, pair->one, &p_lines, &p_ends); @@ -1004,6 +993,7 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang c_context, c_reset, opt->file); } +out: free(p_ends); free(t_ends); } @@ -1014,7 +1004,10 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang */ static void dump_diff_hacky(struct rev_info *rev, struct line_log_data *range) { - fprintf(rev->diffopt.file, "%s\n", output_prefix(&rev->diffopt)); + const char *prefix = diff_line_prefix(&rev->diffopt); + + fprintf(rev->diffopt.file, "%s\n", prefix); + while (range) { dump_diff_hacky_one(rev, range); range = range->next; @@ -1034,6 +1027,7 @@ static int process_diff_filepair(struct rev_info *rev, struct range_set tmp; struct diff_ranges diff; mmfile_t file_parent, file_target; + char *parent_data_to_free = NULL; assert(pair->two->path); while (rg) { @@ -1058,7 +1052,7 @@ static int process_diff_filepair(struct rev_info *rev, file_parent.ptr = pair->one->data; file_parent.size = pair->one->size; } else { - file_parent.ptr = ""; + file_parent.ptr = parent_data_to_free = xstrdup(""); file_parent.size = 0; } @@ -1077,6 +1071,7 @@ static int process_diff_filepair(struct rev_info *rev, diff_ranges_release(&diff); + free(parent_data_to_free); return ((*diff_out)->parent.nr > 0); } @@ -1093,7 +1088,7 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair) static void free_diffqueues(int n, struct diff_queue_struct *dq) { for (int i = 0; i < n; i++) - diff_free_queue(&dq[i]); + diff_queue_clear(&dq[i]); free(dq); } @@ -1128,10 +1123,18 @@ static int process_all_files(struct line_log_data **range_out, while (rg && strcmp(rg->path, pair->two->path)) rg = rg->next; assert(rg); + if (rg->pair) + diff_free_filepair(rg->pair); rg->pair = diff_filepair_dup(queue->queue[i]); + diff_ranges_release(&rg->diff); memcpy(&rg->diff, pairdiff, sizeof(struct diff_ranges)); + FREE_AND_NULL(pairdiff); + } + + if (pairdiff) { + diff_ranges_release(pairdiff); + free(pairdiff); } - free(pairdiff); } return changed; @@ -1196,7 +1199,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c if (parent) add_line_range(rev, parent, parent_range); free_line_log_data(parent_range); - diff_free_queue(&queue); + diff_queue_clear(&queue); return changed; } @@ -1209,12 +1212,13 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm struct commit_list *p; int i; int nparents = commit_list_count(commit->parents); + int ret; if (nparents > 1 && rev->first_parent_only) nparents = 1; ALLOC_ARRAY(diffqueues, nparents); - ALLOC_ARRAY(cand, nparents); + CALLOC_ARRAY(cand, nparents); ALLOC_ARRAY(parents, nparents); p = commit->parents; @@ -1226,7 +1230,6 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm for (i = 0; i < nparents; i++) { int changed; - cand[i] = NULL; changed = process_all_files(&cand[i], rev, &diffqueues[i], range); if (!changed) { /* @@ -1234,13 +1237,11 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm * don't follow any other path in history */ add_line_range(rev, parents[i], cand[i]); - clear_commit_line_range(rev, commit); + free_commit_list(commit->parents); commit_list_append(parents[i], &commit->parents); - free(parents); - free(cand); - free_diffqueues(nparents, diffqueues); - /* NEEDSWORK leaking like a sieve */ - return 0; + + ret = 0; + goto out; } } @@ -1248,18 +1249,25 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm * No single parent took the blame. We add the candidates * from the above loop to the parents. */ - for (i = 0; i < nparents; i++) { + for (i = 0; i < nparents; i++) add_line_range(rev, parents[i], cand[i]); - } + ret = 1; + +out: clear_commit_line_range(rev, commit); free(parents); + for (i = 0; i < nparents; i++) { + if (!cand[i]) + continue; + line_log_data_clear(cand[i]); + free(cand[i]); + } free(cand); free_diffqueues(nparents, diffqueues); - return 1; + return ret; /* NEEDSWORK evil merge detection stuff */ - /* NEEDSWORK leaking like a sieve */ } int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit *commit) |