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