Coverage Report

Created: 2023-06-07 07:02

/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
  This program is free software; you can redistribute it and/or modify it
7
  under the terms of the GNU General Public License as published by the
8
  Free Software Foundation; version 3.
9
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU General Public License for more details.
14
15
  You should have received a copy of the GNU General Public License
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18
19
  To the extent this program is licensed as part of the Enterprise
20
  versions of CFEngine, the applicable Commercial Open Source License
21
  (COSL) may apply to this file if you as a licensee so wish it. See
22
  included file COSL.txt.
23
*/
24
25
#ifndef CFENGINE_SET_H
26
#define CFENGINE_SET_H
27
28
#include <map.h>
29
#include <buffer.h>
30
#include <json.h>
31
#include <alloc.h> // xvasprintf
32
33
typedef Map Set;
34
typedef MapIterator SetIterator;
35
typedef void *(*SetElementCopyFn)(const void *);
36
37
Set *SetNew(MapHashFn element_hash_fn,
38
            MapKeyEqualFn element_equal_fn,
39
            MapDestroyDataFn element_destroy_fn);
40
void SetDestroy(Set *set);
41
42
void SetAdd(Set *set, void *element);
43
void SetJoin(Set *set, Set *otherset, SetElementCopyFn copy_function);
44
bool SetContains(const Set *set, const void *element);
45
bool SetRemove(Set *set, const void *element);
46
void SetClear(Set *set);
47
size_t SetSize(const Set *set);
48
49
bool SetIsEqual(const Set *set1, const Set *set2);
50
51
SetIterator SetIteratorInit(Set *set);
52
void *SetIteratorNext(SetIterator *i);
53
54
#define TYPED_SET_DECLARE(Prefix, ElementType)                          \
55
    typedef struct                                                      \
56
    {                                                                   \
57
        Set *impl;                                                      \
58
    } Prefix##Set;                                                      \
59
    typedef ElementType(*Prefix##CopyFn)(const ElementType);            \
60
                                                                        \
61
    typedef SetIterator Prefix##SetIterator;                            \
62
                                                                        \
63
    Prefix##Set *Prefix##SetNew(void);                                  \
64
    void Prefix##SetAdd(const Prefix##Set *set, ElementType element);   \
65
    void Prefix##SetJoin(const Prefix##Set *set, const Prefix##Set *otherset, Prefix##CopyFn copy_function); \
66
    bool Prefix##SetContains(const Prefix##Set *Set, const ElementType element);  \
67
    bool Prefix##SetRemove(const Prefix##Set *Set, const ElementType element);  \
68
    void Prefix##SetClear(Prefix##Set *set);                            \
69
    size_t Prefix##SetSize(const Prefix##Set *set);                     \
70
    bool Prefix##SetIsEqual(const Prefix##Set *set1, const Prefix##Set *set2); \
71
    void Prefix##SetDestroy(Prefix##Set *set);                          \
72
    Prefix##SetIterator Prefix##SetIteratorInit(Prefix##Set *set);      \
73
    ElementType Prefix##SetIteratorNext(Prefix##SetIterator *iter);     \
74
75
#define TYPED_SET_DEFINE(Prefix, ElementType, hash_fn, equal_fn, destroy_fn) \
76
                                                                        \
77
    Prefix##Set *Prefix##SetNew(void)                                   \
78
    {                                                                   \
79
        Prefix##Set *set = xcalloc(1, sizeof(Prefix##Set));             \
80
        set->impl = SetNew(hash_fn, equal_fn, destroy_fn);              \
81
        return set;                                                     \
82
    }                                                                   \
83
                                                                        \
84
    void Prefix##SetAdd(const Prefix##Set *set, ElementType element)    \
85
    {                                                                   \
86
        SetAdd(set->impl, (void *)element);                             \
87
    }                                                                   \
88
                                                                        \
89
    void Prefix##SetJoin(const Prefix##Set *set, const Prefix##Set *otherset, Prefix##CopyFn copy_function) \
90
    {                                                                   \
91
        SetJoin(set->impl, otherset->impl, (SetElementCopyFn) copy_function);              \
92
    }                                                                   \
93
                                                                        \
94
    bool Prefix##SetContains(const Prefix##Set *set, const ElementType element)   \
95
    {                                                                   \
96
        return SetContains(set->impl, element);                         \
97
    }                                                                   \
98
                                                                        \
99
    bool Prefix##SetRemove(const Prefix##Set *set, const ElementType element)   \
100
    {                                                                   \
101
        return SetRemove(set->impl, element);                           \
102
    }                                                                   \
103
                                                                        \
104
    void Prefix##SetClear(Prefix##Set *set)                             \
105
    {                                                                   \
106
        SetClear(set->impl);                                            \
107
    }                                                                   \
108
                                                                        \
109
    size_t Prefix##SetSize(const Prefix##Set *set)                      \
110
    {                                                                   \
111
        return SetSize(set->impl);                                      \
112
    }                                                                   \
113
                                                                        \
114
    bool Prefix##SetIsEqual(const Prefix##Set *set1, const Prefix##Set *set2) \
115
    {                                                                   \
116
        return SetIsEqual(set1->impl, set2->impl);                      \
117
    }                                                                   \
118
                                                                        \
119
    void Prefix##SetDestroy(Prefix##Set *set)                           \
120
    {                                                                   \
121
        if (set)                                                        \
122
        {                                                               \
123
            SetDestroy(set->impl);                                      \
124
            free(set);                                                  \
125
        }                                                               \
126
    }                                                                   \
127
                                                                        \
128
    Prefix##SetIterator Prefix##SetIteratorInit(Prefix##Set *set)       \
129
    {                                                                   \
130
        return SetIteratorInit(set->impl);                              \
131
    }                                                                   \
132
                                                                        \
133
    ElementType Prefix##SetIteratorNext(Prefix##SetIterator *iter)      \
134
    {                                                                   \
135
        return SetIteratorNext(iter);                                   \
136
    }                                                                   \
137
138
139
TYPED_SET_DECLARE(String, char *)
140
141
void StringSetAddSplit(StringSet *set, const char *str, char delimiter);
142
StringSet *StringSetFromString(const char *str, char delimiter);
143
Buffer *StringSetToBuffer(StringSet *set, const char delimiter);
144
JsonElement *StringSetToJson(const StringSet *set);
145
146
/**
147
 * Convert a flat JSON array into a #StringSet.
148
 */
149
StringSet *JsonArrayToStringSet(const JsonElement *array);
150
151
/**
152
 * Format and add string to set.
153
 * @param[in] set string set.
154
 * @param[in] fmt format string.
155
 * @param[in] va variable-length argument list.
156
 */
157
FUNC_ATTR_PRINTF(2, 3) static inline void StringSetAddF(StringSet *const set, const char *const fmt, ...)
158
0
{
159
0
    assert(set != NULL);
160
0
    assert(fmt != NULL);
161
0
162
0
    va_list args;
163
0
    va_start(args, fmt);
164
0
165
0
    char *str;
166
0
    NDEBUG_UNUSED int ret = xvasprintf(&str, fmt, args);
167
0
    assert(ret >= 0);
168
0
169
0
    va_end(args);
170
0
    StringSetAdd(set, str);
171
0
}
172
173
#endif