Blame src/diff_parse.c

Packit ae9e2a
/*
Packit ae9e2a
 * Copyright (C) the libgit2 contributors. All rights reserved.
Packit ae9e2a
 *
Packit ae9e2a
 * This file is part of libgit2, distributed under the GNU GPL v2 with
Packit ae9e2a
 * a Linking Exception. For full terms see the included COPYING file.
Packit ae9e2a
 */
Packit ae9e2a
#include "common.h"
Packit ae9e2a
#include "diff.h"
Packit ae9e2a
#include "diff_parse.h"
Packit ae9e2a
#include "patch.h"
Packit ae9e2a
#include "patch_parse.h"
Packit ae9e2a
Packit ae9e2a
static void diff_parsed_free(git_diff *d)
Packit ae9e2a
{
Packit ae9e2a
	git_diff_parsed *diff = (git_diff_parsed *)d;
Packit ae9e2a
	git_patch *patch;
Packit ae9e2a
	size_t i;
Packit ae9e2a
Packit ae9e2a
	git_vector_foreach(&diff->patches, i, patch)
Packit ae9e2a
		git_patch_free(patch);
Packit ae9e2a
Packit ae9e2a
	git_vector_free(&diff->patches);
Packit ae9e2a
Packit ae9e2a
	git_vector_free(&diff->base.deltas);
Packit ae9e2a
	git_pool_clear(&diff->base.pool);
Packit ae9e2a
Packit ae9e2a
	git__memzero(diff, sizeof(*diff));
Packit ae9e2a
	git__free(diff);
Packit ae9e2a
}
Packit ae9e2a
Packit ae9e2a
static git_diff_parsed *diff_parsed_alloc(void)
Packit ae9e2a
{
Packit ae9e2a
	git_diff_parsed *diff;
Packit ae9e2a
Packit ae9e2a
	if ((diff = git__calloc(1, sizeof(git_diff_parsed))) == NULL)
Packit ae9e2a
		return NULL;
Packit ae9e2a
Packit ae9e2a
	GIT_REFCOUNT_INC(diff);
Packit ae9e2a
	diff->base.type = GIT_DIFF_TYPE_PARSED;
Packit ae9e2a
	diff->base.strcomp = git__strcmp;
Packit ae9e2a
	diff->base.strncomp = git__strncmp;
Packit ae9e2a
	diff->base.pfxcomp = git__prefixcmp;
Packit ae9e2a
	diff->base.entrycomp = git_diff__entry_cmp;
Packit ae9e2a
	diff->base.patch_fn = git_patch_parsed_from_diff;
Packit ae9e2a
	diff->base.free_fn = diff_parsed_free;
Packit ae9e2a
Packit ae9e2a
	if (git_diff_init_options(&diff->base.opts, GIT_DIFF_OPTIONS_VERSION) < 0) {
Packit ae9e2a
		git__free(diff);
Packit ae9e2a
		return NULL;
Packit ae9e2a
	}
Packit ae9e2a
Packit ae9e2a
	diff->base.opts.flags &= ~GIT_DIFF_IGNORE_CASE;
Packit ae9e2a
Packit ae9e2a
	git_pool_init(&diff->base.pool, 1);
Packit ae9e2a
Packit ae9e2a
	if (git_vector_init(&diff->patches, 0, NULL) < 0 ||
Packit ae9e2a
		git_vector_init(&diff->base.deltas, 0, git_diff_delta__cmp) < 0) {
Packit ae9e2a
		git_diff_free(&diff->base);
Packit ae9e2a
		return NULL;
Packit ae9e2a
	}
Packit ae9e2a
Packit ae9e2a
	git_vector_set_cmp(&diff->base.deltas, git_diff_delta__cmp);
Packit ae9e2a
Packit ae9e2a
	return diff;
Packit ae9e2a
}
Packit ae9e2a
Packit ae9e2a
int git_diff_from_buffer(
Packit ae9e2a
	git_diff **out,
Packit ae9e2a
	const char *content,
Packit ae9e2a
	size_t content_len)
Packit ae9e2a
{
Packit ae9e2a
	git_diff_parsed *diff;
Packit ae9e2a
	git_patch *patch;
Packit ae9e2a
	git_patch_parse_ctx *ctx = NULL;
Packit ae9e2a
	int error = 0;
Packit ae9e2a
Packit ae9e2a
	*out = NULL;
Packit ae9e2a
Packit ae9e2a
	diff = diff_parsed_alloc();
Packit ae9e2a
	GITERR_CHECK_ALLOC(diff);
Packit ae9e2a
Packit ae9e2a
	ctx = git_patch_parse_ctx_init(content, content_len, NULL);
Packit ae9e2a
	GITERR_CHECK_ALLOC(ctx);
Packit ae9e2a
Packit ae9e2a
	while (ctx->remain_len) {
Packit ae9e2a
		if ((error = git_patch_parse(&patch, ctx)) < 0)
Packit ae9e2a
			break;
Packit ae9e2a
Packit ae9e2a
		git_vector_insert(&diff->patches, patch);
Packit ae9e2a
		git_vector_insert(&diff->base.deltas, patch->delta);
Packit ae9e2a
	}
Packit ae9e2a
Packit ae9e2a
	if (error == GIT_ENOTFOUND && git_vector_length(&diff->patches) > 0) {
Packit ae9e2a
		giterr_clear();
Packit ae9e2a
		error = 0;
Packit ae9e2a
	}
Packit ae9e2a
Packit ae9e2a
	git_patch_parse_ctx_free(ctx);
Packit ae9e2a
Packit ae9e2a
	if (error < 0)
Packit ae9e2a
		git_diff_free(&diff->base);
Packit ae9e2a
	else
Packit ae9e2a
		*out = &diff->base;
Packit ae9e2a
Packit ae9e2a
	return error;
Packit ae9e2a
}
Packit ae9e2a