Line Flow Count Block(s) Source
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 -
8 - #include "commit_list.h"
9 -
10 - #include "revwalk.h"
11 - #include "pool.h"
12 - #include "odb.h"
13 - #include "commit.h"
14 -
15 9890 2 int git_commit_list_time_cmp(const void *a, const void *b)
16 - {
17 9890 2 int64_t time_a = ((git_commit_list_node *) a)->time;
18 9890 2 int64_t time_b = ((git_commit_list_node *) b)->time;
19 -
20 9890 2 if (time_a < time_b)
21 4898 3 return 1;
22 4992 4 if (time_a > time_b)
23 4384 5 return -1;
24 -
25 608 6 return 0;
26 - }
27 -
28 5607 2 git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
29 - {
30 5607 2 git_commit_list *new_list = git__malloc(sizeof(git_commit_list));
31 5607 3 if (new_list != NULL) {
32 5607 4 new_list->item = item;
33 5607 4 new_list->next = *list_p;
34 - }
35 5607 5 *list_p = new_list;
36 5607 5 return new_list;
37 - }
38 -
39 1255 2 git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p)
40 - {
41 1255 2 git_commit_list **pp = list_p;
42 - git_commit_list *p;
43 -
44 2224 2,7 while ((p = *pp) != NULL) {
45 1545 3,4 if (git_commit_list_time_cmp(p->item, item) > 0)
46 576 5 break;
47 -
48 969 6 pp = &p->next;
49 - }
50 -
51 1255 8 return git_commit_list_insert(item, pp);
52 - }
53 -
54 3752 2 git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk)
55 - {
56 3752 2 return (git_commit_list_node *)git_pool_mallocz(&walk->commit_pool, 1);
57 - }
58 -
59 3682 2 static git_commit_list_node **alloc_parents(
60 - git_revwalk *walk, git_commit_list_node *commit, size_t n_parents)
61 - {
62 - size_t bytes;
63 -
64 3682 2 if (n_parents <= PARENTS_PER_COMMIT)
65 3676 3 return (git_commit_list_node **)((char *)commit + sizeof(git_commit_list_node));
66 -
67 6 4,5 if (git__multiply_sizet_overflow(&bytes, n_parents, sizeof(git_commit_list_node *)))
68 ##### 6 return NULL;
69 -
70 6 7 return (git_commit_list_node **)git_pool_malloc(&walk->commit_pool, bytes);
71 - }
72 -
73 -
74 3010 2 void git_commit_list_free(git_commit_list **list_p)
75 - {
76 3010 2 git_commit_list *list = *list_p;
77 -
78 3010 2 if (list == NULL)
79 3010 3,8 return;
80 -
81 2788 4,6 while (list) {
82 2240 5 git_commit_list *temp = list;
83 2240 5 list = temp->next;
84 2240 5 git__free(temp);
85 - }
86 -
87 548 7 *list_p = NULL;
88 - }
89 -
90 3490 2 git_commit_list_node *git_commit_list_pop(git_commit_list **stack)
91 - {
92 3490 2 git_commit_list *top = *stack;
93 3490 2-4 git_commit_list_node *item = top ? top->item : NULL;
94 -
95 3490 5 if (top) {
96 3367 6 *stack = top->next;
97 3367 6 git__free(top);
98 - }
99 3490 7 return item;
100 - }
101 -
102 3682 2 static int commit_quick_parse(
103 - git_revwalk *walk,
104 - git_commit_list_node *node,
105 - git_odb_object *obj)
106 - {
107 - git_oid *parent_oid;
108 - git_commit *commit;
109 - int error;
110 - size_t i;
111 -
112 3682 2 commit = git__calloc(1, sizeof(*commit));
113 3682 3,4 GIT_ERROR_CHECK_ALLOC(commit);
114 3682 5 commit->object.repo = walk->repo;
115 -
116 3682 5,6 if ((error = git_commit__parse_ext(commit, obj, GIT_COMMIT_PARSE_QUICK)) < 0) {
117 ##### 7 git__free(commit);
118 ##### 8 return error;
119 - }
120 -
121 3682 9,10 if (!git__is_uint16(git_array_size(commit->parent_ids))) {
122 ##### 11 git__free(commit);
123 ##### 12 git_error_set(GIT_ERROR_INVALID, "commit has more than 2^16 parents");
124 ##### 13 return -1;
125 - }
126 -
127 3682 14 node->time = commit->committer->when.time;
128 3682 14 node->out_degree = (uint16_t) git_array_size(commit->parent_ids);
129 3682 14 node->parents = alloc_parents(walk, node, node->out_degree);
130 3682 15,16 GIT_ERROR_CHECK_ALLOC(node->parents);
131 -
132 7291 17,19-21 git_array_foreach(commit->parent_ids, i, parent_oid) {
133 3609 18 node->parents[i] = git_revwalk__commit_lookup(walk, parent_oid);
134 - }
135 -
136 3682 22 git_commit__free(commit);
137 -
138 3682 23 node->parsed = 1;
139 -
140 3682 23 return 0;
141 - }
142 -
143 5384 2 int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
144 - {
145 - git_odb_object *obj;
146 - int error;
147 -
148 5384 2 if (commit->parsed)
149 1702 3 return 0;
150 -
151 3682 4,5 if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0)
152 ##### 6 return error;
153 -
154 3682 7 if (obj->cached.type != GIT_OBJECT_COMMIT) {
155 ##### 8 git_error_set(GIT_ERROR_INVALID, "object is no commit object");
156 ##### 9 error = -1;
157 - } else
158 3682 10 error = commit_quick_parse(walk, commit, obj);
159 -
160 3682 11 git_odb_object_free(obj);
161 3682 12 return error;
162 - }
163 -