Raw
1 #include "git-compat-util.h"
2 #include "oidset.h"
3 #include "hex.h"
4 #include "strbuf.h"
5
6 void oidset_init(struct oidset *set, size_t initial_size)
7 {
8 memset(&set->set, 0, sizeof(set->set));
9 if (initial_size)
10 kh_resize_oid_set(&set->set, initial_size);
11 }
12
13 int oidset_contains(const struct oidset *set, const struct object_id *oid)
14 {
15 khiter_t pos = kh_get_oid_set(&set->set, *oid);
16 return pos != kh_end(&set->set);
17 }
18
19 bool oidset_equal(const struct oidset *a, const struct oidset *b)
20 {
21 struct oidset_iter iter;
22 struct object_id *a_oid;
23
24 if (oidset_size(a) != oidset_size(b))
25 return false;
26
27 oidset_iter_init(a, &iter);
28 while ((a_oid = oidset_iter_next(&iter)))
29 if (!oidset_contains(b, a_oid))
30 return false;
31
32 return true;
33 }
34
35 int oidset_insert(struct oidset *set, const struct object_id *oid)
36 {
37 int added;
38 kh_put_oid_set(&set->set, *oid, &added);
39 return !added;
40 }
41
42 void oidset_insert_from_set(struct oidset *dest, struct oidset *src)
43 {
44 struct oidset_iter iter;
45 struct object_id *src_oid;
46
47 oidset_iter_init(src, &iter);
48 while ((src_oid = oidset_iter_next(&iter)))
49 oidset_insert(dest, src_oid);
50 }
51
52 int oidset_remove(struct oidset *set, const struct object_id *oid)
53 {
54 khiter_t pos = kh_get_oid_set(&set->set, *oid);
55 if (pos == kh_end(&set->set))
56 return 0;
57 kh_del_oid_set(&set->set, pos);
58 return 1;
59 }
60
61 void oidset_clear(struct oidset *set)
62 {
63 kh_release_oid_set(&set->set);
64 oidset_init(set, 0);
65 }
66
67 void oidset_parse_file(struct oidset *set, const char *path,
68 const struct git_hash_algo *algop)
69 {
70 oidset_parse_file_carefully(set, path, algop, NULL, NULL);
71 }
72
73 void oidset_parse_file_carefully(struct oidset *set, const char *path,
74 const struct git_hash_algo *algop,
75 oidset_parse_tweak_fn fn, void *cbdata)
76 {
77 FILE *fp;
78 struct strbuf sb = STRBUF_INIT;
79 struct object_id oid;
80
81 fp = fopen(path, "r");
82 if (!fp)
83 die("could not open object name list: %s", path);
84 while (!strbuf_getline(&sb, fp)) {
85 const char *p;
86 const char *name;
87
88 /*
89 * Allow trailing comments, leading whitespace
90 * (including before commits), and empty or whitespace
91 * only lines.
92 */
93 name = strchr(sb.buf, '#');
94 if (name)
95 strbuf_setlen(&sb, name - sb.buf);
96 strbuf_trim(&sb);
97 if (!sb.len)
98 continue;
99
100 if (parse_oid_hex_algop(sb.buf, &oid, &p, algop) || *p != '\0')
101 die("invalid object name: %s", sb.buf);
102 if (fn && fn(&oid, cbdata))
103 continue;
104 oidset_insert(set, &oid);
105 }
106 if (ferror(fp))
107 die_errno("Could not read '%s'", path);
108 fclose(fp);
109 strbuf_release(&sb);
110 }