NeoMutt  2025-01-09-117-gace867
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
slist.c
Go to the documentation of this file.
1
36#include "config.h"
37#include <stdbool.h>
38#include <stddef.h>
39#include <stdint.h>
40#include "mutt/lib.h"
41#include "set.h"
42#include "types.h"
43
47static void slist_destroy(void *var, const struct ConfigDef *cdef)
48{
49 struct Slist **l = (struct Slist **) var;
50 if (!*l)
51 return;
52
53 slist_free(l);
54}
55
59static int slist_string_set(void *var, struct ConfigDef *cdef,
60 const char *value, struct Buffer *err)
61{
62 /* Store empty string list as NULL */
63 if (value && (value[0] == '\0'))
64 value = NULL;
65
66 struct Slist *list = NULL;
67
68 int rc = CSR_SUCCESS;
69
70 if (var)
71 {
72 list = slist_parse(value, cdef->type);
73
74 if (slist_equal(list, *(struct Slist **) var))
75 {
76 slist_free(&list);
78 }
79
80 if (startup_only(cdef, err))
81 {
82 slist_free(&list);
84 }
85
86 if (cdef->validator)
87 {
88 rc = cdef->validator(cdef, (intptr_t) list, err);
89
90 if (CSR_RESULT(rc) != CSR_SUCCESS)
91 {
92 slist_free(&list);
93 return rc | CSR_INV_VALIDATOR;
94 }
95 }
96
97 slist_destroy(var, cdef);
98
99 *(struct Slist **) var = list;
100
101 if (!list)
102 rc |= CSR_SUC_EMPTY;
103 }
104 else
105 {
106 if (cdef->type & D_INTERNAL_INITIAL_SET)
107 FREE(&cdef->initial);
108
110 cdef->initial = (intptr_t) mutt_str_dup(value);
111 }
112
113 return rc;
114}
115
119static int slist_string_get(void *var, const struct ConfigDef *cdef, struct Buffer *result)
120{
121 if (var)
122 {
123 struct Slist *list = *(struct Slist **) var;
124 if (!list)
125 return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
126
127 slist_to_buffer(list, result);
128 }
129 else
130 {
131 buf_addstr(result, (char *) cdef->initial);
132 }
133
134 int rc = CSR_SUCCESS;
135 if (buf_is_empty(result))
136 rc |= CSR_SUC_EMPTY;
137
138 return rc;
139}
140
144static int slist_native_set(void *var, const struct ConfigDef *cdef,
145 intptr_t value, struct Buffer *err)
146{
147 int rc;
148
149 if (slist_equal((struct Slist *) value, *(struct Slist **) var))
151
152 if (startup_only(cdef, err))
154
155 if (cdef->validator)
156 {
157 rc = cdef->validator(cdef, value, err);
158
159 if (CSR_RESULT(rc) != CSR_SUCCESS)
160 return rc | CSR_INV_VALIDATOR;
161 }
162
163 slist_free(var);
164
165 struct Slist *list = slist_dup((struct Slist *) value);
166
167 rc = CSR_SUCCESS;
168 if (!list)
169 rc |= CSR_SUC_EMPTY;
170
171 *(struct Slist **) var = list;
172 return rc;
173}
174
178static intptr_t slist_native_get(void *var, const struct ConfigDef *cdef, struct Buffer *err)
179{
180 struct Slist *list = *(struct Slist **) var;
181
182 return (intptr_t) list;
183}
184
188static int slist_string_plus_equals(void *var, const struct ConfigDef *cdef,
189 const char *value, struct Buffer *err)
190{
191 int rc = CSR_SUCCESS;
192
193 /* Store empty strings as NULL */
194 if (value && (value[0] == '\0'))
195 value = NULL;
196
197 if (!value)
198 return rc | CSR_SUC_NO_CHANGE;
199
200 if (startup_only(cdef, err))
202
203 struct Slist *orig = *(struct Slist **) var;
204 if (slist_is_member(orig, value))
205 return rc | CSR_SUC_NO_CHANGE;
206
207 struct Slist *copy = slist_dup(orig);
208 if (!copy)
209 copy = slist_new(cdef->type & D_SLIST_SEP_MASK);
210
211 slist_add_string(copy, value);
212
213 if (cdef->validator)
214 {
215 rc = cdef->validator(cdef, (intptr_t) copy, err);
216 if (CSR_RESULT(rc) != CSR_SUCCESS)
217 {
218 slist_free(&copy);
219 return rc | CSR_INV_VALIDATOR;
220 }
221 }
222
223 slist_free(&orig);
224 *(struct Slist **) var = copy;
225
226 return rc;
227}
228
232static int slist_string_minus_equals(void *var, const struct ConfigDef *cdef,
233 const char *value, struct Buffer *err)
234{
235 int rc = CSR_SUCCESS;
236
237 /* Store empty strings as NULL */
238 if (value && (value[0] == '\0'))
239 value = NULL;
240
241 if (!value)
242 return rc | CSR_SUC_NO_CHANGE;
243
244 if (startup_only(cdef, err))
246
247 struct Slist *orig = *(struct Slist **) var;
248 if (!slist_is_member(orig, value))
249 return rc | CSR_SUC_NO_CHANGE;
250
251 struct Slist *copy = slist_dup(orig);
252 slist_remove_string(copy, value);
253
254 if (cdef->validator)
255 {
256 rc = cdef->validator(cdef, (intptr_t) copy, err);
257 if (CSR_RESULT(rc) != CSR_SUCCESS)
258 {
259 slist_free(&copy);
260 return rc | CSR_INV_VALIDATOR;
261 }
262 }
263
264 slist_free(&orig);
265 *(struct Slist **) var = copy;
266
267 return rc;
268}
269
273static bool slist_has_been_set(void *var, const struct ConfigDef *cdef)
274{
275 struct Slist *list = NULL;
276 const char *initial = (const char *) cdef->initial;
277
278 if (initial)
279 list = slist_parse(initial, cdef->type);
280
281 bool rc = !slist_equal(list, *(struct Slist **) var);
282 slist_free(&list);
283 return rc;
284}
285
289static int slist_reset(void *var, const struct ConfigDef *cdef, struct Buffer *err)
290{
291 struct Slist *list = NULL;
292 const char *initial = (const char *) cdef->initial;
293
294 if (initial)
295 list = slist_parse(initial, cdef->type);
296
297 if (slist_equal(list, *(struct Slist **) var))
298 {
299 slist_free(&list);
301 }
302
303 if (startup_only(cdef, err))
304 {
305 slist_free(&list);
307 }
308
309 int rc = CSR_SUCCESS;
310
311 if (cdef->validator)
312 {
313 rc = cdef->validator(cdef, (intptr_t) list, err);
314
315 if (CSR_RESULT(rc) != CSR_SUCCESS)
316 {
317 slist_destroy(&list, cdef);
318 return rc | CSR_INV_VALIDATOR;
319 }
320 }
321
322 if (!list)
323 rc |= CSR_SUC_EMPTY;
324
325 slist_destroy(var, cdef);
326
327 *(struct Slist **) var = list;
328 return rc;
329}
330
334const struct ConfigSetType CstSlist = {
335 DT_SLIST,
336 "slist",
346};
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
static bool startup_only(const struct ConfigDef *cdef, struct Buffer *err)
Validator function for D_ON_STARTUP.
Definition: set.h:293
#define CSR_ERR_INVALID
Value hasn't been set.
Definition: set.h:36
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:46
#define CSR_SUC_NO_CHANGE
The value hasn't changed.
Definition: set.h:42
#define CSR_RESULT(x)
Definition: set.h:50
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:40
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:33
const struct ConfigSetType CstSlist
Config type representing a list of strings.
Definition: slist.c:334
static void slist_destroy(void *var, const struct ConfigDef *cdef)
Destroy an Slist object - Implements ConfigSetType::destroy() -.
Definition: slist.c:47
static bool slist_has_been_set(void *var, const struct ConfigDef *cdef)
Is the config value different to its initial value? - Implements ConfigSetType::has_been_set() -.
Definition: slist.c:273
static intptr_t slist_native_get(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get a Slist from a Slist config item - Implements ConfigSetType::native_get() -.
Definition: slist.c:178
static int slist_native_set(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:144
static int slist_reset(void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset a Slist to its initial value - Implements ConfigSetType::reset() -.
Definition: slist.c:289
static int slist_string_get(void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get a Slist as a string - Implements ConfigSetType::string_get() -.
Definition: slist.c:119
static int slist_string_minus_equals(void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Remove from a Slist by string - Implements ConfigSetType::string_minus_equals() -.
Definition: slist.c:232
static int slist_string_plus_equals(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:188
static int slist_string_set(void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set a Slist by string - Implements ConfigSetType::string_set() -.
Definition: slist.c:59
#define FREE(x)
Definition: memory.h:55
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:235
struct Slist * slist_parse(const char *str, uint32_t flags)
Parse a list of strings into a list.
Definition: slist.c:177
void slist_free(struct Slist **ptr)
Free an Slist object.
Definition: slist.c:124
bool slist_equal(const struct Slist *a, const struct Slist *b)
Compare two string lists.
Definition: slist.c:91
struct Slist * slist_add_string(struct Slist *list, const char *str)
Add a string to a list.
Definition: slist.c:68
bool slist_is_member(const struct Slist *list, const char *str)
Is a string a member of a list?
Definition: slist.c:154
struct Slist * slist_dup(const struct Slist *list)
Create a copy of an Slist object.
Definition: slist.c:108
int slist_to_buffer(const struct Slist *list, struct Buffer *buf)
Export an Slist to a Buffer.
Definition: slist.c:269
struct Slist * slist_new(uint32_t flags)
Create a new string list.
Definition: slist.c:51
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:254
Parse the 'set' command.
String manipulation buffer.
Definition: buffer.h:36
Definition: set.h:62
int(* validator)(const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Definition: set.h:79
intptr_t initial
Initial value.
Definition: set.h:65
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:64
String list.
Definition: slist.h:37
Constants for all the config types.
#define D_SLIST_SEP_MASK
Definition: types.h:112
#define D_INTERNAL_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:89
@ DT_SLIST
a list of strings
Definition: types.h:42