NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
slist.c
Go to the documentation of this file.
1
35#include "config.h"
36#include <stddef.h>
37#include <limits.h>
38#include <stdint.h>
39#include "mutt/lib.h"
40#include "set.h"
41#include "types.h"
42
46static void slist_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
47{
48 if (!cs || !var || !cdef)
49 return; /* LCOV_EXCL_LINE */
50
51 struct Slist **l = (struct Slist **) var;
52 if (!*l)
53 return;
54
55 slist_free(l);
56}
57
61static int slist_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
62 const char *value, struct Buffer *err)
63{
64 if (!cs || !cdef)
65 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
66
67 /* Store empty string list as NULL */
68 if (value && (value[0] == '\0'))
69 value = NULL;
70
71 struct Slist *list = NULL;
72
73 int rc = CSR_SUCCESS;
74
75 if (var)
76 {
77 list = slist_parse(value, cdef->type);
78
79 if (cdef->validator)
80 {
81 rc = cdef->validator(cs, cdef, (intptr_t) list, err);
82
83 if (CSR_RESULT(rc) != CSR_SUCCESS)
84 {
85 slist_free(&list);
86 return (rc | CSR_INV_VALIDATOR);
87 }
88 }
89
90 slist_destroy(cs, var, cdef);
91
92 *(struct Slist **) var = list;
93
94 if (!list)
95 rc |= CSR_SUC_EMPTY;
96 }
97 else
98 {
99 if (cdef->type & DT_INITIAL_SET)
100 FREE(&cdef->initial);
101
102 cdef->type |= DT_INITIAL_SET;
103 cdef->initial = (intptr_t) mutt_str_dup(value);
104 }
105
106 return rc;
107}
108
112static int slist_string_get(const struct ConfigSet *cs, void *var,
113 const struct ConfigDef *cdef, struct Buffer *result)
114{
115 if (!cs || !cdef)
116 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
117
118 if (var)
119 {
120 struct Slist *list = *(struct Slist **) var;
121 if (!list)
122 return (CSR_SUCCESS | CSR_SUC_EMPTY); /* empty string */
123
124 slist_to_buffer(list, result);
125 }
126 else
127 {
128 mutt_buffer_addstr(result, (char *) cdef->initial);
129 }
130
131 int rc = CSR_SUCCESS;
132 if (mutt_buffer_is_empty(result))
133 rc |= CSR_SUC_EMPTY;
134
135 return rc;
136}
137
141static int slist_native_set(const struct ConfigSet *cs, void *var,
142 const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
143{
144 if (!cs || !var || !cdef)
145 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
146
147 int rc;
148
149 if (cdef->validator)
150 {
151 rc = cdef->validator(cs, cdef, value, err);
152
153 if (CSR_RESULT(rc) != CSR_SUCCESS)
154 return (rc | CSR_INV_VALIDATOR);
155 }
156
157 slist_free(var);
158
159 struct Slist *list = slist_dup((struct Slist *) value);
160
161 rc = CSR_SUCCESS;
162 if (!list)
163 rc |= CSR_SUC_EMPTY;
164
165 *(struct Slist **) var = list;
166 return rc;
167}
168
172static intptr_t slist_native_get(const struct ConfigSet *cs, void *var,
173 const struct ConfigDef *cdef, struct Buffer *err)
174{
175 if (!cs || !var || !cdef)
176 return INT_MIN; /* LCOV_EXCL_LINE */
177
178 struct Slist *list = *(struct Slist **) var;
179
180 return (intptr_t) list;
181}
182
186static int slist_string_plus_equals(const struct ConfigSet *cs, void *var,
187 const struct ConfigDef *cdef,
188 const char *value, struct Buffer *err)
189{
190 if (!cs || !cdef)
191 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
192
193 int rc = CSR_SUCCESS;
194
195 /* Store empty strings as NULL */
196 if (value && (value[0] == '\0'))
197 return rc |= CSR_SUC_NO_CHANGE;
198
199 struct Slist *orig = *(struct Slist **) var;
200 if (slist_is_member(orig, value))
201 return rc |= CSR_SUC_NO_CHANGE;
202
203 struct Slist *copy = slist_dup(orig);
204 if (!copy)
205 copy = slist_new(cdef->type & SLIST_SEP_MASK);
206
207 slist_add_string(copy, value);
208
209 if (cdef->validator)
210 {
211 rc = cdef->validator(cs, cdef, (intptr_t) copy, err);
212 if (CSR_RESULT(rc) != CSR_SUCCESS)
213 {
214 slist_free(&copy);
215 return (rc | CSR_INV_VALIDATOR);
216 }
217 }
218
219 slist_free(&orig);
220 *(struct Slist **) var = copy;
221
222 return rc;
223}
224
228static int slist_string_minus_equals(const struct ConfigSet *cs, void *var,
229 const struct ConfigDef *cdef,
230 const char *value, struct Buffer *err)
231{
232 if (!cs || !cdef)
233 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
234
235 int rc = CSR_SUCCESS;
236
237 /* Store empty strings as NULL */
238 if (value && (value[0] == '\0'))
239 return rc |= CSR_SUC_NO_CHANGE;
240
241 struct Slist *orig = *(struct Slist **) var;
242 if (!slist_is_member(orig, value))
243 return rc |= CSR_SUC_NO_CHANGE;
244
245 struct Slist *copy = slist_dup(orig);
246 slist_remove_string(copy, value);
247
248 if (cdef->validator)
249 {
250 rc = cdef->validator(cs, cdef, (intptr_t) copy, err);
251 if (CSR_RESULT(rc) != CSR_SUCCESS)
252 {
253 slist_free(&copy);
254 return (rc | CSR_INV_VALIDATOR);
255 }
256 }
257
258 slist_free(&orig);
259 *(struct Slist **) var = copy;
260
261 return rc;
262}
263
267static int slist_reset(const struct ConfigSet *cs, void *var,
268 const struct ConfigDef *cdef, struct Buffer *err)
269{
270 if (!cs || !var || !cdef)
271 return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
272
273 struct Slist *list = NULL;
274 const char *initial = (const char *) cdef->initial;
275
276 if (initial)
277 list = slist_parse(initial, cdef->type);
278
279 int rc = CSR_SUCCESS;
280
281 if (cdef->validator)
282 {
283 rc = cdef->validator(cs, cdef, (intptr_t) list, err);
284
285 if (CSR_RESULT(rc) != CSR_SUCCESS)
286 {
287 slist_destroy(cs, &list, cdef);
288 return (rc | CSR_INV_VALIDATOR);
289 }
290 }
291
292 if (!list)
293 rc |= CSR_SUC_EMPTY;
294
295 slist_destroy(cs, var, cdef);
296
297 *(struct Slist **) var = list;
298 return rc;
299}
300
304const struct ConfigSetType CstSlist = {
305 DT_SLIST,
306 "slist",
315};
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
const struct ConfigSetType CstSlist
Config type representing a list of strings.
Definition: slist.c:304
static void slist_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Destroy an Slist object - Implements ConfigSetType::destroy() -.
Definition: slist.c:46
static intptr_t slist_native_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get a Slist from a Slist config item - Implements ConfigSetType::native_get() -.
Definition: slist.c:172
static int slist_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set a Slist config item by Slist - Implements ConfigSetType::native_set() -.
Definition: slist.c:141
static int slist_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset a Slist to its initial value - Implements ConfigSetType::reset() -.
Definition: slist.c:267
static int slist_string_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get a Slist as a string - Implements ConfigSetType::string_get() -.
Definition: slist.c:112
static int slist_string_minus_equals(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Remove from a Slist by string - Implements ConfigSetType::string_plus_equals() -.
Definition: slist.c:228
static int slist_string_plus_equals(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Add to a Slist by string - Implements ConfigSetType::string_plus_equals() -.
Definition: slist.c:186
static int slist_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set a Slist by string - Implements ConfigSetType::string_set() -.
Definition: slist.c:61
#define FREE(x)
Definition: memory.h:43
Convenience wrapper for the library headers.
struct Slist * slist_remove_string(struct Slist *list, const char *str)
Remove a string from a list.
Definition: slist.c:258
struct Slist * slist_parse(const char *str, uint32_t flags)
Parse a list of strings into a list.
Definition: slist.c:200
struct Slist * slist_add_string(struct Slist *list, const char *str)
Add a string to a list.
Definition: slist.c:80
bool slist_is_member(const struct Slist *list, const char *str)
Is a string a member of a list?
Definition: slist.c:177
struct Slist * slist_dup(const struct Slist *list)
Create a copy of an Slist object.
Definition: slist.c:120
int slist_to_buffer(const struct Slist *list, struct Buffer *buf)
Export an Slist to a Buffer.
Definition: slist.c:292
struct Slist * slist_new(uint32_t flags)
Create a new string list.
Definition: slist.c:43
void slist_free(struct Slist **list)
Free an Slist object.
Definition: slist.c:162
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
A collection of config items.
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
#define CSR_SUC_NO_CHANGE
The value hasn't changed.
Definition: set.h:44
#define CSR_ERR_CODE
Problem with the code.
Definition: set.h:36
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define SLIST_SEP_MASK
Definition: slist.h:37
String manipulation buffer.
Definition: buffer.h:34
Definition: set.h:64
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:82
intptr_t initial
Initial value.
Definition: set.h:67
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
Container for lots of config items.
Definition: set.h:260
String list.
Definition: slist.h:47
Constants for all the config types.
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:79
#define DT_SLIST
a list of strings
Definition: types.h:39