/src/core/libntech/libutils/set.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright 2023 Northern.tech AS |
3 | | |
4 | | This file is part of CFEngine 3 - written and maintained by Northern.tech AS. |
5 | | |
6 | | Licensed under the Apache License, Version 2.0 (the "License"); |
7 | | you may not use this file except in compliance with the License. |
8 | | You may obtain a copy of the License at |
9 | | |
10 | | http://www.apache.org/licenses/LICENSE-2.0 |
11 | | |
12 | | Unless required by applicable law or agreed to in writing, software |
13 | | distributed under the License is distributed on an "AS IS" BASIS, |
14 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | | See the License for the specific language governing permissions and |
16 | | limitations under the License. |
17 | | |
18 | | To the extent this program is licensed as part of the Enterprise |
19 | | versions of CFEngine, the applicable Commercial Open Source License |
20 | | (COSL) may apply to this file if you as a licensee so wish it. See |
21 | | included file COSL.txt. |
22 | | */ |
23 | | |
24 | | #ifndef CFENGINE_SET_H |
25 | | #define CFENGINE_SET_H |
26 | | |
27 | | #include <map.h> |
28 | | #include <buffer.h> |
29 | | #include <json.h> |
30 | | #include <alloc.h> // xvasprintf |
31 | | |
32 | | typedef Map Set; |
33 | | typedef MapIterator SetIterator; |
34 | | typedef void *(*SetElementCopyFn)(const void *); |
35 | | |
36 | | Set *SetNew(MapHashFn element_hash_fn, |
37 | | MapKeyEqualFn element_equal_fn, |
38 | | MapDestroyDataFn element_destroy_fn); |
39 | | void SetDestroy(Set *set); |
40 | | |
41 | | void SetAdd(Set *set, void *element); |
42 | | void SetJoin(Set *set, Set *otherset, SetElementCopyFn copy_function); |
43 | | bool SetContains(const Set *set, const void *element); |
44 | | bool SetRemove(Set *set, const void *element); |
45 | | void SetClear(Set *set); |
46 | | size_t SetSize(const Set *set); |
47 | | |
48 | | bool SetIsEqual(const Set *set1, const Set *set2); |
49 | | |
50 | | SetIterator SetIteratorInit(Set *set); |
51 | | void *SetIteratorNext(SetIterator *i); |
52 | | |
53 | | #define TYPED_SET_DECLARE(Prefix, ElementType) \ |
54 | | typedef struct \ |
55 | | { \ |
56 | | Set *impl; \ |
57 | | } Prefix##Set; \ |
58 | | typedef ElementType(*Prefix##CopyFn)(const ElementType); \ |
59 | | \ |
60 | | typedef SetIterator Prefix##SetIterator; \ |
61 | | \ |
62 | | Prefix##Set *Prefix##SetNew(void); \ |
63 | | void Prefix##SetAdd(const Prefix##Set *set, ElementType element); \ |
64 | | void Prefix##SetJoin(const Prefix##Set *set, const Prefix##Set *otherset, Prefix##CopyFn copy_function); \ |
65 | | bool Prefix##SetContains(const Prefix##Set *Set, const ElementType element); \ |
66 | | bool Prefix##SetRemove(const Prefix##Set *Set, const ElementType element); \ |
67 | | void Prefix##SetClear(Prefix##Set *set); \ |
68 | | size_t Prefix##SetSize(const Prefix##Set *set); \ |
69 | | bool Prefix##SetIsEqual(const Prefix##Set *set1, const Prefix##Set *set2); \ |
70 | | void Prefix##SetDestroy(Prefix##Set *set); \ |
71 | | Prefix##SetIterator Prefix##SetIteratorInit(Prefix##Set *set); \ |
72 | | ElementType Prefix##SetIteratorNext(Prefix##SetIterator *iter); \ |
73 | | |
74 | | #define TYPED_SET_DEFINE(Prefix, ElementType, hash_fn, equal_fn, destroy_fn) \ |
75 | | \ |
76 | | Prefix##Set *Prefix##SetNew(void) \ |
77 | | { \ |
78 | | Prefix##Set *set = xcalloc(1, sizeof(Prefix##Set)); \ |
79 | | set->impl = SetNew(hash_fn, equal_fn, destroy_fn); \ |
80 | | return set; \ |
81 | | } \ |
82 | | \ |
83 | | void Prefix##SetAdd(const Prefix##Set *set, ElementType element) \ |
84 | | { \ |
85 | | SetAdd(set->impl, (void *)element); \ |
86 | | } \ |
87 | | \ |
88 | | void Prefix##SetJoin(const Prefix##Set *set, const Prefix##Set *otherset, Prefix##CopyFn copy_function) \ |
89 | | { \ |
90 | | SetJoin(set->impl, otherset->impl, (SetElementCopyFn) copy_function); \ |
91 | | } \ |
92 | | \ |
93 | | bool Prefix##SetContains(const Prefix##Set *set, const ElementType element) \ |
94 | | { \ |
95 | | return SetContains(set->impl, element); \ |
96 | | } \ |
97 | | \ |
98 | | bool Prefix##SetRemove(const Prefix##Set *set, const ElementType element) \ |
99 | | { \ |
100 | | return SetRemove(set->impl, element); \ |
101 | | } \ |
102 | | \ |
103 | | void Prefix##SetClear(Prefix##Set *set) \ |
104 | | { \ |
105 | | SetClear(set->impl); \ |
106 | | } \ |
107 | | \ |
108 | | size_t Prefix##SetSize(const Prefix##Set *set) \ |
109 | | { \ |
110 | | return SetSize(set->impl); \ |
111 | | } \ |
112 | | \ |
113 | | bool Prefix##SetIsEqual(const Prefix##Set *set1, const Prefix##Set *set2) \ |
114 | | { \ |
115 | | return SetIsEqual(set1->impl, set2->impl); \ |
116 | | } \ |
117 | | \ |
118 | | void Prefix##SetDestroy(Prefix##Set *set) \ |
119 | | { \ |
120 | | if (set) \ |
121 | | { \ |
122 | | SetDestroy(set->impl); \ |
123 | | free(set); \ |
124 | | } \ |
125 | | } \ |
126 | | \ |
127 | | Prefix##SetIterator Prefix##SetIteratorInit(Prefix##Set *set) \ |
128 | | { \ |
129 | | return SetIteratorInit(set->impl); \ |
130 | | } \ |
131 | | \ |
132 | | ElementType Prefix##SetIteratorNext(Prefix##SetIterator *iter) \ |
133 | | { \ |
134 | | return SetIteratorNext(iter); \ |
135 | | } \ |
136 | | |
137 | | |
138 | | TYPED_SET_DECLARE(String, char *) |
139 | | |
140 | | void StringSetAddSplit(StringSet *set, const char *str, char delimiter); |
141 | | StringSet *StringSetFromString(const char *str, char delimiter); |
142 | | Buffer *StringSetToBuffer(StringSet *set, const char delimiter); |
143 | | JsonElement *StringSetToJson(const StringSet *set); |
144 | | |
145 | | /** |
146 | | * Convert a flat JSON array into a #StringSet. |
147 | | */ |
148 | | StringSet *JsonArrayToStringSet(const JsonElement *array); |
149 | | |
150 | | /** |
151 | | * Format and add string to set. |
152 | | * @param[in] set string set. |
153 | | * @param[in] fmt format string. |
154 | | * @param[in] va variable-length argument list. |
155 | | */ |
156 | | FUNC_ATTR_PRINTF(2, 3) static inline void StringSetAddF(StringSet *const set, const char *const fmt, ...) |
157 | 0 | { |
158 | 0 | assert(set != NULL); |
159 | 0 | assert(fmt != NULL); |
160 | 0 |
|
161 | 0 | va_list args; |
162 | 0 | va_start(args, fmt); |
163 | 0 |
|
164 | 0 | char *str; |
165 | 0 | NDEBUG_UNUSED int ret = xvasprintf(&str, fmt, args); |
166 | 0 | assert(ret >= 0); |
167 | 0 |
|
168 | 0 | va_end(args); |
169 | 0 | StringSetAdd(set, str); |
170 | 0 | } |
171 | | |
172 | | #endif |