summaryrefslogtreecommitdiff
path: root/line-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'line-log.c')
-rw-r--r--line-log.c100
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)