Tag
Hash :
0b5ba0d7
Author :
Date :
2019-06-06T16:36:23
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "diff_parse.h"
#include "diff.h"
#include "patch.h"
#include "patch_parse.h"
static void diff_parsed_free(git_diff *d)
{
git_diff_parsed *diff = (git_diff_parsed *)d;
git_patch *patch;
size_t i;
git_vector_foreach(&diff->patches, i, patch)
git_patch_free(patch);
git_vector_free(&diff->patches);
git_vector_free(&diff->base.deltas);
git_pool_clear(&diff->base.pool);
git__memzero(diff, sizeof(*diff));
git__free(diff);
}
static git_diff_parsed *diff_parsed_alloc(void)
{
git_diff_parsed *diff;
if ((diff = git__calloc(1, sizeof(git_diff_parsed))) == NULL)
return NULL;
GIT_REFCOUNT_INC(&diff->base);
diff->base.type = GIT_DIFF_TYPE_PARSED;
diff->base.strcomp = git__strcmp;
diff->base.strncomp = git__strncmp;
diff->base.pfxcomp = git__prefixcmp;
diff->base.entrycomp = git_diff__entry_cmp;
diff->base.patch_fn = git_patch_parsed_from_diff;
diff->base.free_fn = diff_parsed_free;
if (git_diff_options_init(&diff->base.opts, GIT_DIFF_OPTIONS_VERSION) < 0) {
git__free(diff);
return NULL;
}
diff->base.opts.flags &= ~GIT_DIFF_IGNORE_CASE;
git_pool_init(&diff->base.pool, 1);
if (git_vector_init(&diff->patches, 0, NULL) < 0 ||
git_vector_init(&diff->base.deltas, 0, git_diff_delta__cmp) < 0) {
git_diff_free(&diff->base);
return NULL;
}
git_vector_set_cmp(&diff->base.deltas, git_diff_delta__cmp);
return diff;
}
int git_diff_from_buffer(
git_diff **out,
const char *content,
size_t content_len)
{
git_diff_parsed *diff;
git_patch *patch;
git_patch_parse_ctx *ctx = NULL;
int error = 0;
*out = NULL;
diff = diff_parsed_alloc();
GIT_ERROR_CHECK_ALLOC(diff);
ctx = git_patch_parse_ctx_init(content, content_len, NULL);
GIT_ERROR_CHECK_ALLOC(ctx);
while (ctx->parse_ctx.remain_len) {
if ((error = git_patch_parse(&patch, ctx)) < 0)
break;
git_vector_insert(&diff->patches, patch);
git_vector_insert(&diff->base.deltas, patch->delta);
}
if (error == GIT_ENOTFOUND && git_vector_length(&diff->patches) > 0) {
git_error_clear();
error = 0;
}
git_patch_parse_ctx_free(ctx);
if (error < 0)
git_diff_free(&diff->base);
else
*out = &diff->base;
return error;
}