NeoMutt  2022-04-29-145-g9b6a0e
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 
46 static 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 
61 static 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 
112 static 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 
141 static 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 
172 static 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 
186 static 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 
228 static 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 
267 static 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 
304 const struct ConfigSetType CstSlist = {
305  DT_SLIST,
306  "slist",
313  slist_reset,
315 };
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:250
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:223
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_dup(const struct Slist *list)
Create a copy of an Slist object.
Definition: slist.c:120
struct Slist * slist_new(uint32_t flags)
Create a new string list.
Definition: slist.c:43
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_remove_string(struct Slist *list, const char *str)
Remove a string from a list.
Definition: slist.c:258
int slist_to_buffer(const struct Slist *list, struct Buffer *buf)
Export an Slist to a Buffer.
Definition: slist.c:292
struct Slist * slist_parse(const char *str, uint32_t flags)
Parse a list of strings into a list.
Definition: slist.c:200
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